home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 15 code / 3D Interface / Demo3D / U3DDrawing.cp < prev    next >
Encoding:
Text File  |  1994-10-21  |  115.1 KB  |  3,921 lines  |  [TEXT/MPS ]

  1. //----------------------------------------------------------------------------------------
  2. //    File:        U3DDrawing.cp
  3. //
  4. //    Contains:    Adorners, classes, etc for 3D drawing effects
  5. //
  6. //    Written by:    Jamie Osborne, Robin Mair, Faulkner White, Henri Lamiraux
  7. //                 Adapted for 3.1.1 by Jeroen Schalk
  8. //
  9. //    Copyright:    © 1992-1994 by Apple Computer, Inc.
  10. //
  11. // Some notes:
  12. //    1.  This code makes your controls non-internationalized.  If you wish
  13. //        to make the controls draw with the correct system orientation
  14. //        (e.g. right to left for Hebrew), you need to check the gEnvironment
  15. //        variable and setup your drawing rects correctly.
  16. //    2.  This code IS compatible with non-Color Quickdraw machines.
  17. //    3.    On slower machines (anything slower than an '030), this code will
  18. //        be slow.  You should take this into account if you use this library
  19. //        in your application.  Test it out on a slower machine to see if
  20. //        it is still fast enough for your needs.  If it IS too slow, there
  21. //        are many opportunities in the code for optimization.  One example
  22. //        is removing some of the CGraphicsState objects from some of the
  23. //        routines and replacing them with CPenNormal();
  24. //    4.  If you have any questions about the code, please direct them to
  25. //        Jamie Osborne (AppleLink: JWO; Internet: jwo@applelink.apple.com).
  26. //----------------------------------------------------------------------------------------
  27.  
  28. #ifndef __QUICKDRAW__
  29. #include <Quickdraw.h>
  30. #endif
  31.  
  32. #ifndef __RESOURCES__
  33. #include <Resources.h>
  34. #endif
  35.  
  36. #ifndef __U3DDRAWING__
  37. #include "U3DDrawing.h"
  38. #endif
  39.  
  40. //----------------------------------------------------------------------------------------
  41. // InitU3DDrawing        Include this routine in your initialization function
  42. //----------------------------------------------------------------------------------------
  43. #pragma segment AInit
  44.  
  45. void InitU3DDrawing()
  46. {
  47.     macroDontDeadStrip(TGrayBackgroundAdorner);
  48.     macroDontDeadStrip(TWhiteBackgroundAdorner);
  49.     macroDontDeadStrip(T3DGrayBackgroundAdorner);
  50.     macroDontDeadStrip(T3DFrameAdorner);
  51.     macroDontDeadStrip(T3DLineTopAdorner);
  52.     macroDontDeadStrip(T3DLineBottomAdorner);
  53.     macroDontDeadStrip(T3DLineRightAdorner);
  54.     macroDontDeadStrip(T3DLineLeftAdorner);
  55.  
  56.     macroDontDeadStrip(T3DCheckBox);
  57.     macroDontDeadStrip(T3DRadio);
  58.     macroDontDeadStrip(T3DButton);
  59.  
  60.     macroDontDeadStrip(T3DIconAdorner);
  61.     macroDontDeadStrip(TIconSuite);
  62.     macroDontDeadStrip(T3DIconButton);
  63. }
  64.  
  65. //----------------------------------------------------------------------------------------
  66. // ••• 3D Utility Classes •••
  67. //----------------------------------------------------------------------------------------
  68.  
  69. //----------------------------------------------------------------------------------------
  70. // CLASS: CGraphicsState
  71. //----------------------------------------------------------------------------------------
  72. //
  73. // This class is used to save and restore the current Quickdraw graphics state.
  74. // Create one of these objects at the beginning of a drawing method then use it to
  75. // save and restore the state of the graphics before and after your drawing.  When
  76. // one of these objects is created the Constructor saves off the current settings
  77. // for the fore and background colors, the pen state and the current textstyle.  It
  78. // also does a PenNormal() call in preparation for drawing.  The destructor will just
  79. // reverse this process.  Two methods are provided that allow an explicit Save() and
  80. // Restore() that mimic the constructor and destructor.  These method can be called
  81. // if you want to reuse the same object during drawing.  The destructor will use the
  82. // last values saved.
  83.  
  84. //----------------------------------------------------------------------------------------
  85. // CGraphicsState::CGraphicsState
  86. //----------------------------------------------------------------------------------------
  87. //
  88. // Initialize the instance variables of the object by saving the current state
  89. // of some of the current port settings.
  90.  
  91. #pragma segment AUtils
  92.  
  93. CGraphicsState::CGraphicsState ()
  94. {
  95.      // • First save off the foreground and background colors and the penstate
  96.     GetIfColor ( fSaveForeColor );
  97.     GetIfBkColor ( fSaveBackColor );
  98.     GetPenState ( &fSavePenState );
  99.     CPenNormal ();
  100.  
  101.     // • Now save off the current port's textstyle information
  102.     GetPortTextStyle ( fSaveTextStyle );
  103.  
  104. } // CGraphicsState::CGraphicsState
  105.  
  106. //----------------------------------------------------------------------------------------
  107. // CGraphicsState::~CGraphicsState
  108. //----------------------------------------------------------------------------------------
  109. //
  110. // The destructor simply restores the last Save() state when it is called
  111.  
  112. #pragma segment AUtils
  113.  
  114. CGraphicsState::~CGraphicsState ()
  115. {
  116.     // • Restore the foreground and background colors and the penstate
  117.     SetIfColor ( fSaveForeColor );
  118.     SetIfBkColor ( fSaveBackColor );
  119.     SetPenState ( &fSavePenState );
  120.  
  121.     // • Now restore the textstyle of the current port
  122.     SetPortTextStyle ( fSaveTextStyle );
  123.  
  124. } // CGraphicsState::~CGraphicsState
  125.  
  126. //----------------------------------------------------------------------------------------
  127. // CGraphicsState::Save
  128. //----------------------------------------------------------------------------------------
  129. //
  130. // Save off the current graphics state so that we can restore it again
  131. // after we are done with our drawing.  Also calls PenNormal () to set the
  132. // pen to the Quickdraw defaults.
  133.  
  134. #pragma segment AUtils
  135.  
  136. void CGraphicsState::Save ()
  137. {
  138.      // • First save off the foreground and background colors and the penstate
  139.     GetIfColor ( fSaveForeColor );
  140.     GetIfBkColor ( fSaveBackColor );
  141.     GetPenState ( &fSavePenState );
  142.     CPenNormal ();
  143.  
  144.     // • Now save off the current port's textstyle information
  145.     GetPortTextStyle ( fSaveTextStyle );
  146.  
  147. } // CGraphicsState::Save
  148.  
  149. //----------------------------------------------------------------------------------------
  150. // CGraphicsState::Restore
  151. //----------------------------------------------------------------------------------------
  152. //
  153. // Restores the graphics state, this is typically called after doing some drawing
  154. // and after we have created an instance of this class or called the Save () method.
  155.  
  156. #pragma segment AUtils
  157.  
  158. void CGraphicsState::Restore ()
  159. {
  160.     // • Restore the foreground and background colors and the penstate
  161.     SetIfColor ( fSaveForeColor );
  162.     SetIfBkColor ( fSaveBackColor );
  163.     SetPenState ( &fSavePenState );
  164.  
  165.     // • Now restore the textstyle of the current port
  166.     SetPortTextStyle ( fSaveTextStyle );
  167.  
  168. } // CGraphicsState::Restore
  169.  
  170. //----------------------------------------------------------------------------------------
  171. // Class CDrawPerDevice
  172. //----------------------------------------------------------------------------------------
  173.  
  174. //----------------------------------------------------------------------------------------
  175. // CDrawPerDevice::CDrawPerDevice
  176. //----------------------------------------------------------------------------------------
  177. #pragma segment AUtils
  178.  
  179. CDrawPerDevice::CDrawPerDevice()
  180. {
  181.     // • Initialize our instance variables
  182.     fSaveClip = NULL;
  183.     fGDHandle = NULL;
  184.  
  185. } // CDrawPerDevice::CDrawPerDevice
  186.  
  187. //----------------------------------------------------------------------------------------
  188. // CDrawPerDevice::CDrawPerDevice
  189. //----------------------------------------------------------------------------------------
  190. #pragma segment AUtils
  191.  
  192. CDrawPerDevice::CDrawPerDevice ( const CRect& area )
  193. {
  194.     // • Initialize our fields
  195.     fSaveClip = NULL;
  196.     fGDHandle = NULL;
  197.  
  198.     // • Save off the area passed in and convert it to global coordinates
  199.     fGlobalArea = area;
  200.     LocalToGlobal ( fGlobalArea[topLeft] );
  201.     LocalToGlobal ( fGlobalArea[botRight] );
  202.  
  203.     // Remember the View port info
  204.     fFocus.itsViewPortInfo.clip = MakeNewRgn();
  205.     GetFocus(fFocus);
  206.  
  207.     fSaveClip = fFocus.itsViewPortInfo.clip;
  208.  
  209.     // Set a placeholder for non Color QD drawing
  210.     fDoneOldQD = false;
  211. } // CDrawPerDevice::CDrawPerDevice
  212.  
  213. //----------------------------------------------------------------------------------------
  214. // CDrawPerDevice::~CDrawPerDevice
  215. //----------------------------------------------------------------------------------------
  216. #pragma segment AUtils
  217.  
  218. CDrawPerDevice::~CDrawPerDevice()
  219. {
  220.     // Restore the port information
  221.     SetFocus(fFocus);
  222.  
  223.     // • If we have a saved clip then make sure that we displose of the region
  224.     fFocus.itsViewPortInfo.clip = DisposeIfRgnHandle(fFocus.itsViewPortInfo.clip);
  225.  
  226. } // CDrawPerDevice::~CDrawPerDevice
  227.  
  228. //----------------------------------------------------------------------------------------
  229. // CDrawPerDevice::SetDrawingArea
  230. //----------------------------------------------------------------------------------------
  231. //
  232. // This does the same thing as the constructor and can be used to reset the drawing
  233. // area at anytime
  234.  
  235. #pragma segment AUtils
  236.  
  237. void CDrawPerDevice::SetDrawingArea ( const CRect& area )
  238. {
  239.     // • Save off the area passed in and convert it to global coordinates
  240.     fGlobalArea = area;
  241.     LocalToGlobal ( fGlobalArea[topLeft] );
  242.     LocalToGlobal ( fGlobalArea[botRight] );
  243.  
  244.     // • Get a handle to the first device in the device list
  245.     fGDHandle = GetDeviceList ();
  246.  
  247.     // Remember the View port info
  248.     fFocus.itsViewPortInfo.clip = MakeNewRgn();
  249.     GetFocus(fFocus);
  250.  
  251.     fSaveClip = fFocus.itsViewPortInfo.clip;
  252.  
  253. } // CDrawPerDevice::SetDrawingArea
  254.  
  255. //----------------------------------------------------------------------------------------
  256. // CDrawPerDevice::NextDevice
  257. //----------------------------------------------------------------------------------------
  258. //
  259. // This is the method that is called during the drawing process.  What it does is
  260. // cycle through each of the devices in the device list, returning the pixel size for
  261. // the device, it also sets the clipping to the portion of the drawing area that is
  262. // in need of drawing on the current device
  263.  
  264. #pragma segment AUtils
  265.  
  266. Boolean CDrawPerDevice::NextDevice ( short& pixelSize )
  267. {
  268.     Boolean foundActiveScreen = false;
  269.     CRect    bounds;
  270.     CRect area;
  271.  
  272.     // Go ye not into this code if ye have not Color Quickdraw
  273.     if (!gConfiguration.hasColorQD)
  274.     {
  275.         pixelSize = 1;
  276.         foundActiveScreen = !fDoneOldQD;
  277.         fDoneOldQD = !fDoneOldQD;
  278.         return foundActiveScreen;
  279.     }
  280.  
  281.     // • We will iterate over the device list while there are devices.  As we do this
  282.     // are returning the pixel size of the current device and setting the clipping to
  283.     // the area of that device that is in need of redrawing
  284.  
  285.     if (fGDHandle == NULL)
  286.         fGDHandle = GetDeviceList();
  287.     else
  288.         fGDHandle = GetNextDevice(fGDHandle);
  289.  
  290.     while ((fGDHandle != NULL) && (foundActiveScreen == false))
  291.     {
  292.            if (TestDeviceAttribute(fGDHandle, screenDevice) &&
  293.                TestDeviceAttribute(fGDHandle, screenActive))
  294.         {
  295.             foundActiveScreen = true;
  296.             pixelSize = (*(*fGDHandle)->gdPMap)->pixelSize;
  297.  
  298.             // • Get the bounds of the current device
  299.             bounds = (*fGDHandle)->gdRect;
  300.             if ( SectRect ( bounds, fGlobalArea, area ) )
  301.             {
  302.                 // • Convert the overlapping area to local coordinates
  303.                 GlobalToLocal ( area[topLeft] );
  304.                 GlobalToLocal ( area[botRight] );
  305.  
  306.                 // • Create a temporary region and convert the overlapped area to a region
  307.                 CTemporaryRegion    tempRgn;
  308.                 RectRgn ( tempRgn, area );
  309.  
  310.                 // • Set the temporary region to the intersection between the area and the
  311.                 // saved clipping region
  312.                 SectRgn ( tempRgn, fSaveClip, tempRgn );
  313.                 // Clip to the visregion,too
  314.                 SectRgn(tempRgn, qd.thePort->visRgn, tempRgn);
  315.  
  316.                 // • Set the clip to the overlap
  317.                 SetClip ( tempRgn );
  318.  
  319.             }
  320.             else
  321.             {
  322.                 foundActiveScreen = false;
  323.                 fGDHandle = GetNextDevice(fGDHandle);
  324.             }
  325.         }
  326.         else
  327.             fGDHandle = GetNextDevice(fGDHandle);
  328.     }
  329.  
  330.     return foundActiveScreen;
  331.  
  332. } // CDrawPerDevice::NextDevice
  333.  
  334. //----------------------------------------------------------------------------------------
  335. // CPenNormal    - a color version of PenNormal()
  336. //----------------------------------------------------------------------------------------
  337. #pragma segment AUtils
  338.  
  339. void CPenNormal()
  340. {
  341.     RGBForeColor(gRGBBlack);
  342.     RGBBackColor(gRGBWhite);
  343.     PenNormal();
  344.  
  345. } // CPenNormal
  346.  
  347. //----------------------------------------------------------------------------------------
  348. // ••• 3D TView Adorners •••
  349. //----------------------------------------------------------------------------------------
  350. #pragma segment A3DOpen
  351.  
  352. #undef Inherited
  353. #define Inherited TAdorner
  354. DefineClass(TWhiteBackgroundAdorner, Inherited);
  355.  
  356. TWhiteBackgroundAdorner::TWhiteBackgroundAdorner()
  357. {
  358. }
  359.  
  360. //----------------------------------------------------------------------------------------
  361. #pragma segment A3DOpen
  362.  
  363. void TWhiteBackgroundAdorner::IWhiteBackgroundAdorner(Boolean freeOnDeletion)
  364. {
  365.     this->IAdorner(kWhiteBackgroundAdorner,freeOnDeletion);
  366.  
  367. } // T3DWhiteBackgroundAdorner::I3DWhiteBackgroundAdorner
  368.  
  369. //----------------------------------------------------------------------------------------
  370. #pragma segment A3DRes
  371.  
  372. void TWhiteBackgroundAdorner::Draw(TView* itsView, const VRect& area)
  373. {
  374.     CRect            qdArea;
  375.     short            pixelSize;
  376.     CGraphicsState     rememberGState;
  377.  
  378.     itsView->ViewToQDRect(area, qdArea);
  379.  
  380.     CDrawPerDevice device(qdArea);
  381.     while (device.NextDevice(pixelSize))
  382.     {
  383.         // Only draw us if we are on a non B & W monitor
  384.         if (pixelSize >= 4)
  385.         {
  386.             SetIfBkColor(gRGBWhite);
  387.             EraseRect(qdArea);
  388.         }
  389.     }
  390. } // TWhiteBackgroundAdorner::Draw
  391.  
  392. //----------------------------------------------------------------------------------------
  393. #pragma segment A3DOpen
  394.  
  395. #undef Inherited
  396. #define Inherited TAdorner
  397. DefineClass(TGrayBackgroundAdorner, Inherited);
  398.  
  399. TGrayBackgroundAdorner::TGrayBackgroundAdorner()
  400. {
  401. }
  402.  
  403. //----------------------------------------------------------------------------------------
  404. #pragma segment A3DOpen
  405.  
  406. void TGrayBackgroundAdorner::IGrayBackgroundAdorner(Boolean freeOnDeletion)
  407. {
  408.     this->IAdorner(kGrayBackgroundAdorner,freeOnDeletion);
  409.  
  410. } // T3DGrayBackgroundAdorner::I3DGrayBackgroundAdorner
  411.  
  412. //----------------------------------------------------------------------------------------
  413. #pragma segment A3DRes
  414.  
  415. void TGrayBackgroundAdorner::Draw(TView* itsView, const VRect& area)
  416. {
  417.  
  418.     CRect            qdArea;
  419.     short            pixelSize;
  420.     CGraphicsState     rememberGState;
  421.  
  422.     itsView->ViewToQDRect(area, qdArea);
  423.  
  424.     CDrawPerDevice device(qdArea);
  425.     while (device.NextDevice(pixelSize))
  426.     {
  427.         if (pixelSize >= 4)
  428.         {
  429.             // Erase because we want our subviews to draw on gray
  430.             SetIfBkColor(kLightGray);
  431.             EraseRect(qdArea);
  432.         }
  433.     }
  434. } // TGrayBackgroundAdorner::Draw
  435.  
  436. //----------------------------------------------------------------------------------------
  437. #pragma segment A3DOpen
  438.  
  439. #undef Inherited
  440. #define Inherited TGrayBackgroundAdorner
  441. DefineClass(T3DGrayBackgroundAdorner, Inherited);
  442.  
  443. T3DGrayBackgroundAdorner::T3DGrayBackgroundAdorner()
  444. {
  445. }
  446.  
  447. //----------------------------------------------------------------------------------------
  448. #pragma segment A3DOpen
  449.  
  450. void T3DGrayBackgroundAdorner::I3DGrayBackgroundAdorner(Boolean freeOnDeletion)
  451. {
  452.     this->IGrayBackgroundAdorner(freeOnDeletion);
  453.  
  454. } // T3DGrayBackgroundAdorner::I3DGrayBackgroundAdorner
  455.  
  456. //----------------------------------------------------------------------------------------
  457. #pragma segment A3DRes
  458.  
  459. void T3DGrayBackgroundAdorner::Draw(TView* itsView, const VRect& area)
  460. {
  461.     CRect            qdArea, frame;
  462.     VRect            viewRect;
  463.     short            pixelSize;
  464.     CGraphicsState     rememberGState;
  465.  
  466.     // Erase the background in gray
  467.     Inherited:: Draw(itsView,area);
  468.  
  469.     itsView->ViewToQDRect(area, qdArea);
  470.     itsView->GetAdornExtent(viewRect);
  471.     itsView->ViewToQDRect(viewRect, frame);
  472.  
  473.     CDrawPerDevice device(qdArea);
  474.     while (device.NextDevice(pixelSize))
  475.     {
  476.         // Only draw on non- B & W
  477.         if (pixelSize >= 4)
  478.         {
  479.             SetIfColor(gRGBWhite);
  480.             MoveTo(frame.right-1, frame.top);
  481.             LineTo(frame.left, frame.top);
  482.             LineTo(frame.left, frame.bottom);
  483.  
  484.             SetIfColor(kMediumLightGray);
  485.             MoveTo(frame.left+1, frame.bottom-1);
  486.             LineTo(frame.right-1, frame.bottom-1);
  487.             LineTo(frame.right-1, frame.top+1);
  488.         }
  489.     }
  490.  
  491. } // T3DGrayBackgroundAdorner::Draw
  492.  
  493. //----------------------------------------------------------------------------------------
  494. #pragma segment A3DOpen
  495.  
  496. #undef Inherited
  497. #define Inherited TAdorner
  498. DefineClass(T3DLineTopAdorner, Inherited);
  499.  
  500. T3DLineTopAdorner::T3DLineTopAdorner()
  501. {
  502. }
  503.  
  504. //----------------------------------------------------------------------------------------
  505. #pragma segment A3DOpen
  506.  
  507. void T3DLineTopAdorner::I3DLineTopAdorner(Boolean freeOnDeletion)
  508. {
  509.     this->IAdorner(k3DLineTopAdorner,freeOnDeletion);
  510.  
  511. } // T3DLineTopAdorner::I3DLineTopAdorner
  512.  
  513. //----------------------------------------------------------------------------------------
  514. #pragma segment A3DRes
  515.  
  516. void T3DLineTopAdorner::Draw(TView* itsView, const VRect& area)
  517. {
  518.     CRect            qdArea, frame;
  519.     VRect            viewRect;
  520.     short            pixelSize;
  521.     CGraphicsState  rememberGState;
  522.  
  523.     itsView->ViewToQDRect(area, qdArea);
  524.     itsView->GetAdornExtent(viewRect);
  525.     itsView->ViewToQDRect(viewRect, frame);
  526.  
  527.     CDrawPerDevice device(qdArea);
  528.     while (device.NextDevice(pixelSize))
  529.     {
  530.         // Draw a gray and white line for non- B & W
  531.         if (pixelSize >= 4)
  532.         {
  533.             SetIfColor(kMediumLightGray);
  534.             MoveTo(frame.left, frame.top);
  535.             LineTo(frame.right, frame.top);
  536.  
  537.             SetIfColor(gRGBWhite);
  538.             MoveTo(frame.left, frame.top + 1);
  539.             LineTo(frame.right, frame.top + 1);
  540.         }
  541.         // Draw a regular black line
  542.         else
  543.         {
  544.  
  545.             PenPat(&qd.black);
  546.             MoveTo(frame.left, frame.top);
  547.             LineTo(frame.right, frame.top);
  548.         }
  549.     }
  550.  
  551. } // T3DLineTopAdorner::Draw
  552.  
  553. //----------------------------------------------------------------------------------------
  554. #pragma segment A3DOpen
  555.  
  556. #undef Inherited
  557. #define Inherited TAdorner
  558. DefineClass(T3DLineBottomAdorner, Inherited);
  559.  
  560. T3DLineBottomAdorner::T3DLineBottomAdorner()
  561. {
  562. }
  563.  
  564. //----------------------------------------------------------------------------------------
  565. #pragma segment A3DOpen
  566.  
  567. void T3DLineBottomAdorner::I3DLineBottomAdorner(Boolean freeOnDeletion)
  568. {
  569.     this->IAdorner(k3DLineBottomAdorner,freeOnDeletion);
  570.  
  571. } // T3DLineBottomAdorner::I3DLineBottomAdorner
  572.  
  573. //----------------------------------------------------------------------------------------
  574. #pragma segment A3DRes
  575.  
  576. void T3DLineBottomAdorner::Draw(TView* itsView, const VRect& area)
  577. {
  578.     CRect            qdArea, frame;
  579.     VRect            viewRect;
  580.     short            pixelSize;
  581.     CGraphicsState  rememberGState;
  582.  
  583.     itsView->ViewToQDRect(area, qdArea);
  584.     itsView->GetAdornExtent(viewRect);
  585.     itsView->ViewToQDRect(viewRect, frame);
  586.  
  587.     CDrawPerDevice device(qdArea);
  588.     while (device.NextDevice(pixelSize))
  589.     {
  590.         // Draw a gray and white line for non- B & W
  591.         if (pixelSize >= 4)
  592.         {
  593.             SetIfColor(kMediumLightGray);
  594.             MoveTo(frame.left, frame.bottom - 1);
  595.             LineTo(frame.right, frame.bottom - 1);
  596.  
  597.             SetIfColor(gRGBWhite);
  598.             MoveTo(frame.left, frame.bottom);
  599.             LineTo(frame.right, frame.bottom);
  600.         }
  601.         // Draw a regular black line
  602.         else
  603.         {
  604.  
  605.             PenPat(&qd.black);
  606.             MoveTo(frame.left, frame.bottom - 1);
  607.             LineTo(frame.right, frame.bottom - 1);
  608.         }
  609.     }
  610.  
  611. } // T3DLineBottomAdorner::Draw
  612.  
  613. //----------------------------------------------------------------------------------------
  614. #pragma segment A3DOpen
  615.  
  616. #undef Inherited
  617. #define Inherited TAdorner
  618. DefineClass(T3DLineLeftAdorner, Inherited);
  619.  
  620. T3DLineLeftAdorner::T3DLineLeftAdorner()
  621. {
  622. }
  623.  
  624. //----------------------------------------------------------------------------------------
  625. #pragma segment A3DOpen
  626.  
  627. void T3DLineLeftAdorner::I3DLineLeftAdorner(Boolean freeOnDeletion)
  628. {
  629.     this->IAdorner(k3DLineLeftAdorner,freeOnDeletion);
  630.  
  631. } // T3DLineLeftAdorner::I3DLineLeftAdorner
  632.  
  633. //----------------------------------------------------------------------------------------
  634. #pragma segment A3DRes
  635.  
  636. void T3DLineLeftAdorner::Draw(TView* itsView, const VRect& area)
  637. {
  638.     CRect            qdArea, frame;
  639.     VRect            viewRect;
  640.     short            pixelSize;
  641.     CGraphicsState  rememberGState;
  642.  
  643.     itsView->ViewToQDRect(area, qdArea);
  644.     itsView->GetAdornExtent(viewRect);
  645.     itsView->ViewToQDRect(viewRect, frame);
  646.  
  647.     CDrawPerDevice device(qdArea);
  648.     while (device.NextDevice(pixelSize))
  649.     {
  650.         // Draw a gray and white line for non- B & W
  651.         if (pixelSize >= 4)
  652.         {
  653.             SetIfColor(kMediumLightGray);
  654.             MoveTo(frame.left, frame.top);
  655.             LineTo(frame.left, frame.bottom);
  656.  
  657.             SetIfColor(gRGBWhite);
  658.             MoveTo(frame.left + 1, frame.top);
  659.             LineTo(frame.left + 1, frame.bottom);
  660.         }
  661.         // Draw a regular black line
  662.         else
  663.         {
  664.  
  665.             PenPat(&qd.black);
  666.             MoveTo(frame.left, frame.top);
  667.             LineTo(frame.left, frame.bottom);
  668.         }
  669.     }
  670.  
  671. } // T3DLineLeftAdorner::Draw
  672.  
  673. //----------------------------------------------------------------------------------------
  674. #pragma segment A3DOpen
  675.  
  676. #undef Inherited
  677. #define Inherited TAdorner
  678. DefineClass(T3DLineRightAdorner, Inherited);
  679.  
  680. T3DLineRightAdorner::T3DLineRightAdorner()
  681. {
  682. }
  683.  
  684. //----------------------------------------------------------------------------------------
  685. #pragma segment A3DOpen
  686.  
  687. void T3DLineRightAdorner::I3DLineRightAdorner(Boolean freeOnDeletion)
  688. {
  689.     this->IAdorner(k3DLineRightAdorner,freeOnDeletion);
  690.  
  691. } // T3DLineRightAdorner::I3DLineRightAdorner
  692.  
  693. //----------------------------------------------------------------------------------------
  694. #pragma segment A3DRes
  695.  
  696. void T3DLineRightAdorner::Draw(TView* itsView, const VRect& area)
  697. {
  698.     CRect            qdArea, frame;
  699.     VRect            viewRect;
  700.     short            pixelSize;
  701.     CGraphicsState  rememberGState;
  702.  
  703.     itsView->ViewToQDRect(area, qdArea);
  704.     itsView->GetAdornExtent(viewRect);
  705.     itsView->ViewToQDRect(viewRect, frame);
  706.  
  707.     CDrawPerDevice device(qdArea);
  708.     while (device.NextDevice(pixelSize))
  709.     {
  710.         // Draw a gray and white line for non- B & W
  711.         if (pixelSize >= 4)
  712.         {
  713.             SetIfColor(kMediumLightGray);
  714.             MoveTo(frame.right - 1, frame.top);
  715.             LineTo(frame.right -1, frame.bottom);
  716.  
  717.             SetIfColor(gRGBWhite);
  718.             MoveTo(frame.right, frame.top);
  719.             LineTo(frame.right, frame.bottom);
  720.         }
  721.         // Draw a regular black line
  722.         else
  723.         {
  724.             PenPat(&qd.black);
  725.             MoveTo(frame.right - 1, frame.top);
  726.             LineTo(frame.right - 1, frame.bottom);
  727.         }
  728.     }
  729.  
  730. } // T3DLineRightAdorner::Draw
  731.  
  732. //----------------------------------------------------------------------------------------
  733. #pragma segment A3DOpen
  734.  
  735. #undef Inherited
  736. #define Inherited TAdorner
  737. DefineClass(T3DFrameAdorner, Inherited);
  738.  
  739. T3DFrameAdorner::T3DFrameAdorner()
  740. {
  741. }
  742.  
  743. //----------------------------------------------------------------------------------------
  744. #pragma segment A3DOpen
  745.  
  746. void T3DFrameAdorner::I3DFrameAdorner(Boolean freeOnDeletion)
  747. {
  748.     this->IAdorner(k3DFrameAdorner,freeOnDeletion);
  749.  
  750. } // T3DFrameAdorner::I3DFrameAdorner
  751.  
  752. //----------------------------------------------------------------------------------------
  753. #pragma segment A3DRes
  754.  
  755. void T3DFrameAdorner::Draw(TView* itsView, const VRect& area)
  756. {
  757.     CRect            qdArea, frame;
  758.     VRect            viewRect;
  759.     short            pixelSize;
  760.     CGraphicsState  rememberGState;
  761.  
  762.     itsView->ViewToQDRect(area, qdArea);
  763.     itsView->GetAdornExtent(viewRect);
  764.     itsView->ViewToQDRect(viewRect, frame);
  765.  
  766.     CDrawPerDevice device(qdArea);
  767.     while (device.NextDevice(pixelSize))
  768.     {
  769.         // Draw a gray and white frame with black outline
  770.         if (pixelSize >= 4) {
  771.  
  772.             SetIfColor(kMediumLightGray);
  773.             MoveTo(frame.right, frame.top);
  774.             LineTo(frame.left, frame.top);
  775.             LineTo(frame.left, frame.bottom);
  776.  
  777.             SetIfColor(gRGBWhite);
  778.             MoveTo(frame.left +1, frame.bottom -1);
  779.             LineTo(frame.right -1, frame.bottom -1);
  780.             LineTo(frame.right -1, frame.top + 1);
  781.  
  782.             SetIfColor(gRGBBlack);
  783.             InsetRect(frame, 1, 1);
  784.             FrameRect(frame);
  785.             InsetRect(frame, -1, -1);
  786.         }
  787.         // Draw a regular frame
  788.         else
  789.         {
  790.             PenPat(&qd.black);
  791.             InsetRect(frame, 1, 1);
  792.             FrameRect(frame);
  793.             InsetRect(frame, -1, -1);
  794.         }
  795.     }
  796.  
  797. } // T3DFrameAdorner::Draw
  798.  
  799. //----------------------------------------------------------------------------------------
  800. // ••• TControl classes and auxiliary adorners •••
  801. //----------------------------------------------------------------------------------------
  802.  
  803. //----------------------------------------------------------------------------------------
  804. // T3DCheckBox::Initialize
  805. //----------------------------------------------------------------------------------------
  806. #pragma segment A3DControlOpen
  807.  
  808. #undef Inherited
  809. #define Inherited TCheckBox
  810. DefineClass(T3DCheckBox, Inherited);
  811.  
  812. void T3DCheckBox::Initialize ()                // OVERRIDE
  813. {
  814.     fBackColor = kLightGray;
  815.     fForeColor = gRGBBlack;
  816.     fDrawBox = VRect(1, 0, 15, 14);        // A standard check box is 14x14
  817.  
  818. } // T3DCheckBox::Initialize
  819.  
  820. //----------------------------------------------------------------------------------------
  821. // T3DCheckBox::DoPostCreate
  822. //----------------------------------------------------------------------------------------
  823. #pragma segment A3DControlOpen
  824.  
  825. void T3DCheckBox::DoPostCreate (TDocument *itsDocument) // OVERRIDE
  826. {
  827.     VRect                    theRect;
  828.     TDrawingEnvironment     *environment;
  829.  
  830.     Inherited::DoPostCreate (itsDocument);
  831.  
  832.     // If we have a drawing environment, use it for drawing!
  833.     if (environment = this->GetDrawingEnvironment())
  834.     {
  835.         this->SetBackColor(environment->fBackgroundColor);
  836.         this->InstallColor(environment->fForegroundColor, false);
  837.     }
  838.     this->ControlArea(theRect);
  839.  
  840.     // Center the check box vertically
  841.     long height = theRect.bottom - theRect.top;
  842.     height -= 14;
  843.     long top = height / 2;
  844.     fDrawBox.top += top;
  845.     fDrawBox.bottom += top;
  846.  
  847. } // T3DCheckBox::DoPostCreate
  848.  
  849. //----------------------------------------------------------------------------------------
  850. // T3DCheckBox::I3DCheckBox
  851. //----------------------------------------------------------------------------------------
  852. #pragma segment A3DControlOpen
  853.  
  854. void T3DCheckBox::I3DCheckBox (TView* itsSuperView, const VPoint& itsLocation,
  855.                                  const VPoint& itsSize, SizeDeterminer itsHSizeDet,
  856.                                  SizeDeterminer itsVSizeDet, const CStr255& itsLabel,
  857.                                  Boolean isTurnedOn)
  858. {
  859.     VRect                    theRect;
  860.     TDrawingEnvironment     *environment;
  861.  
  862.     this->ICheckBox (itsSuperView, itsLocation, itsSize,
  863.                      itsHSizeDet, itsVSizeDet, itsLabel, isTurnedOn);
  864.  
  865.     // If we have a drawing environment, use it for drawing!
  866.     if (environment = this->GetDrawingEnvironment())
  867.     {
  868.         this->SetBackColor(environment->fBackgroundColor);
  869.         this->InstallColor(environment->fForegroundColor, false);
  870.     }
  871.     this->ControlArea(theRect);
  872.  
  873.     // Center the check box vertically
  874.     long height = theRect.bottom - theRect.top;
  875.     height -= 14;
  876.     long top = height / 2;
  877.     fDrawBox.top += top;
  878.     fDrawBox.bottom += top;
  879.  
  880. } // T3DCheckBox::I3DCheckBox
  881.  
  882. //----------------------------------------------------------------------------------------
  883. // T3DCheckBox::Clone
  884. //----------------------------------------------------------------------------------------
  885. #pragma segment A3DControlNonRes
  886.  
  887. TObject* T3DCheckBox::Clone ()                // OVERRIDE
  888. {
  889.     T3DCheckBox*    aClonedCheckBox = (T3DCheckBox *)(Inherited::Clone ());
  890.  
  891.     aClonedCheckBox->fBackColor = fBackColor;
  892.     aClonedCheckBox->fForeColor = fForeColor;
  893.  
  894.     return aClonedCheckBox;
  895.  
  896. } // T3DCheckBox::Clone
  897.  
  898. //----------------------------------------------------------------------------------------
  899. // T3DCheckBox::Free
  900. //----------------------------------------------------------------------------------------
  901. #pragma segment A3DControlClose
  902.  
  903. void T3DCheckBox::Free ()                    // OVERRIDE
  904. {
  905.     Inherited::Free ();
  906.  
  907. } // T3DCheckBox::Free
  908.  
  909. //----------------------------------------------------------------------------------------
  910. // T3DCheckBox::Draw:
  911. //----------------------------------------------------------------------------------------
  912. #pragma segment A3DControlRes
  913.  
  914. void T3DCheckBox::Draw (const VRect& /*area*/)
  915. {
  916.     VRect             theRect;
  917.     CRect            qdArea;
  918.     CStr255            label;
  919.     CGraphicsState    remember;
  920.  
  921.     this->ControlArea(theRect);
  922.     this->ViewToQDRect(theRect, qdArea);
  923.  
  924.     this->DrawBox();
  925.     this->DrawCheck();
  926.  
  927.     this->GetText (label);
  928.     CRect textBox = qdArea;
  929.  
  930.     // Move the text 3 pixels to the right of the check box
  931.     textBox.left += (short) fDrawBox.right + 3;
  932.     this->DrawBoxText (label, textBox, false);
  933.  
  934. } // T3DCheckBox::Draw
  935.  
  936. //----------------------------------------------------------------------------------------
  937. // T3DButton::DoMouseCommand
  938. //----------------------------------------------------------------------------------------
  939. #pragma segment A3DControlSelCommand
  940.  
  941. void T3DCheckBox::DoMouseCommand(VPoint& theMouse,
  942.                                 TToolboxEvent* ,
  943.                                 CPoint)        // override
  944. {
  945.     TControlTracker * aControlTracker = new TControlTracker;
  946.     aControlTracker->IControlTracker(this, theMouse);
  947.     this->PostCommand(aControlTracker);
  948. } // T3DCheckBox::DoMouseCommand
  949.  
  950. //----------------------------------------------------------------------------------------
  951. // T3DCheckBox::TrackMouse
  952. //----------------------------------------------------------------------------------------
  953. #pragma segment A3DControlSelCommand
  954.  
  955. void T3DCheckBox::TrackMouse(TrackPhase aTrackPhase,
  956.                              VPoint& ,
  957.                              // anchorPoint
  958.                              VPoint& ,
  959.                              // previousPoint
  960.                              VPoint& nextPoint,
  961.                              Boolean)                            // OVERRIDE
  962. {
  963.     Boolean state = false;
  964.  
  965.     if (! this->IsDimmed())
  966.     {
  967.         switch (aTrackPhase)
  968.         {
  969.         case trackBegin:
  970.             state = fHilite;
  971.             this->HiliteState(true, kRedraw);
  972.             break;
  973.         case trackContinue:
  974.             if (this->ContainsMouse(nextPoint))
  975.                 this->HiliteState(true, kRedraw);
  976.             else
  977.                 this->HiliteState(state, kRedraw);
  978.             break;
  979.         case trackEnd:
  980.             if (this->ContainsMouse(nextPoint))
  981.             {
  982.                 this->HiliteState(false, this->IsOn());
  983.                 this->HandleEvent(fEventNumber, this, NULL);
  984.             }
  985.             break;
  986.         }
  987.     }
  988. }    // T3DCheckBox::TrackMouse
  989.  
  990. //----------------------------------------------------------------------------------------
  991. // T3DCheckBox::SetLongVal:
  992. // Override the way the control works so that we don't call the CDEF
  993. //----------------------------------------------------------------------------------------
  994. #pragma segment A3DControlRes
  995.  
  996. void T3DCheckBox::SetLongVal(VCoordinate itsVal, Boolean /*redraw*/)
  997. {
  998.     itsVal = Max(fLongMin, Min(itsVal, fLongMax));
  999.     if (itsVal != fLongVal)
  1000.     {
  1001.         fLongVal = itsVal;
  1002.         CRect tempRect;
  1003.         this->ViewToQDRect(fDrawBox, tempRect);
  1004.         InsetRect(tempRect, 2,2);
  1005.         this->InvalidateRect(tempRect);
  1006.     }
  1007. } // T3DCheckBox::SetLongVal
  1008.  
  1009. //----------------------------------------------------------------------------------------
  1010. // T3DCheckBox::HiliteState:
  1011. //----------------------------------------------------------------------------------------
  1012. #pragma segment A3DControlNonRes
  1013.  
  1014. void T3DCheckBox::HiliteState(Boolean state,Boolean redraw)
  1015. {
  1016.     if (state != fHilite)
  1017.     {
  1018.         fHilite = state;
  1019.         if (state)                                // hilite adorner draws the hilite state
  1020.             this->AddAdorner(gHiliteAdorner, kAdornLast - 5, kDontRedraw);
  1021.         else
  1022.             this->DeleteAdorner(gHiliteAdorner, kDontRedraw);
  1023.         if (redraw)
  1024.             this->Hilite();
  1025.     }
  1026. } // T3DCheckBox::HiliteState
  1027.  
  1028. //----------------------------------------------------------------------------------------
  1029. // T3DCheckBox::DimState:
  1030. //----------------------------------------------------------------------------------------
  1031. #pragma segment A3DControlNonRes
  1032.  
  1033. void T3DCheckBox::DimState(Boolean state, Boolean redraw)
  1034. {
  1035.     if (state != fDimmed)
  1036.     {
  1037.         fDimmed = state;
  1038.         if (state)                                // dim adorner draws the dim state
  1039.             this->AddAdorner(gDimAdorner, kAdornLast - 10, kDontRedraw);
  1040.         else
  1041.             this->DeleteAdorner(gDimAdorner, kDontRedraw);
  1042.         if (redraw)
  1043.             this->DrawContents();                // Draw change immediately
  1044.     }
  1045. } // T3DCheckBox::DimState
  1046.  
  1047. //----------------------------------------------------------------------------------------
  1048. // T3DCheckBox::Hilite
  1049. //----------------------------------------------------------------------------------------
  1050. #pragma segment A3DControlRes
  1051.  
  1052. void T3DCheckBox::Hilite ()        // OVERRIDE
  1053. {
  1054.     VRect                area;
  1055.     CRect                qdArea, qdBox;
  1056.     CGraphicsState        rememberGState;
  1057.  
  1058. #if qDebug
  1059.     this->AssumeFocused ();
  1060. #endif
  1061.  
  1062.     this->ControlArea (area);
  1063.     this->ViewToQDRect (area, qdArea);
  1064.     this->ViewToQDRect(fDrawBox, qdBox);
  1065.  
  1066.     CPenNormal();
  1067.     if (fHilite)
  1068.     {
  1069.         InsetRect(qdBox, 2, 2);
  1070.         FrameRect(qdBox);
  1071.     }
  1072.     else
  1073.         this->DrawCheck();
  1074. } // T3DCheckBox::Hilite
  1075.  
  1076. //----------------------------------------------------------------------------------------
  1077. // T3DCheckBox::Dim
  1078. //----------------------------------------------------------------------------------------
  1079. #pragma segment A3DControlRes
  1080.  
  1081. void T3DCheckBox::Dim ()        // OVERRIDE
  1082. {
  1083.     VRect             area;
  1084.     CRect             qdArea;
  1085.     CGraphicsState    rememberGState;
  1086.  
  1087.     this->ControlArea (area);
  1088.     area.left += fDrawBox.right;
  1089.     this->ViewToQDRect (area, qdArea);
  1090.  
  1091.     short pixelSize;
  1092.     CDrawPerDevice device(qdArea);
  1093.     while (device.NextDevice (pixelSize))
  1094.     {
  1095.         // If in B & W, do the standard gray pattern.  Non B & W is taken care of in
  1096.         // the DrawCheck and DrawBox routines
  1097.         if (pixelSize < 2)
  1098.         {
  1099.             #if qDebug
  1100.                 this->AssumeFocused ();
  1101.             #endif
  1102.  
  1103.             InsetRect (qdArea, 1, 1);
  1104.  
  1105.             PenPat (&qd.gray);
  1106.             PenMode (patBic);
  1107.             PaintRect (qdArea);
  1108.  
  1109.             InsetRect (qdArea, -1, -1);
  1110.         }
  1111.     }
  1112. } // T3DCheckBox::Dim
  1113.  
  1114. //----------------------------------------------------------------------------------------
  1115. // T3DCheckBox::DrawBoxText
  1116. //----------------------------------------------------------------------------------------
  1117. #pragma segment A3DControlRes
  1118.  
  1119. void T3DCheckBox::DrawBoxText (const CStr255& s, const CRect& box, Boolean preferOutline)
  1120. {
  1121.     FontInfo         theFontInfo;
  1122.     CRect             localBox = box;
  1123.     CRect             qdArea;
  1124.     CGraphicsState    rememberGState;
  1125.  
  1126.     CWhileOutlinePreferred setOP (preferOutline);
  1127.  
  1128.     short textHeight = MAGetFontInfo (theFontInfo);
  1129.     CPoint boxSize = localBox.GetSize ();
  1130.  
  1131.     // Center the text vertically
  1132.     localBox.top += (boxSize.v - textHeight) / 2;
  1133.     MoveTo (localBox.left, localBox.top + theFontInfo.ascent);
  1134.  
  1135.     short pixelSize;
  1136.     CDrawPerDevice device(localBox);
  1137.     while (device.NextDevice (pixelSize))
  1138.     {
  1139.         // If we're dimmed, draw in gray, else draw in the fore color
  1140.         if (pixelSize > 2)
  1141.         {
  1142.             SetIfBkColor(fBackColor);
  1143.             if (this->IsDimmed())
  1144.                 SetIfColor(kMediumGray);
  1145.             else
  1146.                 SetIfColor(fForeColor);
  1147.         }
  1148.         MoveTo (localBox.left, localBox.top + theFontInfo.ascent);
  1149.         DrawString(s);
  1150.     }
  1151.  
  1152. } // T3DCheckBox::DrawBoxText
  1153.  
  1154. //----------------------------------------------------------------------------------------
  1155. // T3DCheckBox::DrawBox
  1156. //----------------------------------------------------------------------------------------
  1157. #pragma segment A3DControlRes
  1158.  
  1159. void T3DCheckBox::DrawBox()
  1160. {
  1161.     CRect            qdBox;
  1162.     short            pixelSize;
  1163.     CGraphicsState    rememberGState;
  1164.  
  1165.     this->ViewToQDRect(fDrawBox, qdBox);
  1166.  
  1167.     CDrawPerDevice device(qdBox);
  1168.     while (device.NextDevice (pixelSize))
  1169.     {
  1170.         // Draw the 3D effect if we're in non B & W
  1171.         if (pixelSize > 2)
  1172.         {
  1173.             if (!this->IsDimmed())
  1174.             {
  1175.                 SetIfColor(gRGBWhite);
  1176.                 MoveTo(qdBox.left+1, qdBox.bottom-1);
  1177.                 LineTo(qdBox.right-1, qdBox.bottom-1);
  1178.                 LineTo(qdBox.right-1, qdBox.top+1);
  1179.  
  1180.                 SetIfColor(kMediumLightGray);
  1181.                 MoveTo(qdBox.right, qdBox.top);
  1182.                 LineTo(qdBox.left, qdBox.top);
  1183.                 LineTo(qdBox.left, qdBox.bottom);
  1184.                 SetIfColor(fForeColor);
  1185.             }
  1186.             else
  1187.                 SetIfColor(kMediumGray);
  1188.         }
  1189.         else
  1190.             SetIfColor(gRGBBlack);
  1191.  
  1192.         // Now draw the regular check box
  1193.         InsetRect(qdBox, 1, 1);
  1194.         FrameRect(qdBox);
  1195.         InsetRect(qdBox, -1, -1);
  1196.     }
  1197. }
  1198.  
  1199. //----------------------------------------------------------------------------------------
  1200. // T3DCheckBox::DrawCheck
  1201. //----------------------------------------------------------------------------------------
  1202. #pragma segment A3DControlRes
  1203.  
  1204. void T3DCheckBox::DrawCheck()
  1205. {
  1206.     CRect            qdBox;
  1207.     CGraphicsState    rememberGState;
  1208.  
  1209.     this->ViewToQDRect(fDrawBox, qdBox);
  1210.  
  1211.     InsetRect(qdBox, 2, 2);
  1212.     SetIfBkColor(gRGBWhite);
  1213.     EraseRect(qdBox);
  1214.  
  1215.     // Draw the check if we're on
  1216.     if (this->IsOn())
  1217.     {
  1218.         short pixelSize;
  1219.         CDrawPerDevice device(qdBox);
  1220.         while (device.NextDevice (pixelSize))
  1221.         {
  1222.             if (pixelSize > 2)
  1223.                 if (this->IsDimmed())
  1224.                     SetIfColor(kMediumGray);
  1225.  
  1226.             MoveTo(qdBox.left-1, qdBox.bottom);
  1227.             LineTo(qdBox.right-1, qdBox.top);
  1228.             MoveTo(qdBox.left, qdBox.top);
  1229.             LineTo(qdBox.right, qdBox.bottom);
  1230.         }
  1231.     }
  1232. }
  1233.  
  1234. //----------------------------------------------------------------------------------------
  1235. // T3DCheckBox::DrawCheck
  1236. // Override because we don't want the Inherited method, which uses the CDEF
  1237. //----------------------------------------------------------------------------------------
  1238. #pragma segment A3DControlRes
  1239.  
  1240. void T3DCheckBox::InstallColor(const CRGBColor& theColor, Boolean redraw)
  1241. {
  1242.     fForeColor = theColor;
  1243.     if (redraw)
  1244.         this->ForceRedraw();
  1245. }
  1246.  
  1247. //----------------------------------------------------------------------------------------
  1248. // T3DRadio::Initialize
  1249. //----------------------------------------------------------------------------------------
  1250. #pragma segment A3DControlOpen
  1251.  
  1252. #undef Inherited
  1253. #define Inherited TRadio
  1254. DefineClass(T3DRadio, TRadio);
  1255.  
  1256. void T3DRadio::Initialize ()                // OVERRIDE
  1257. {
  1258.     fBackColor = kLightGray;
  1259.     fForeColor = gRGBBlack;
  1260.     fDrawBox = VRect(2, 0, 14, 12);        // A radio button is 12x12
  1261.  
  1262. } // T3DRadio::Initialize
  1263.  
  1264. //----------------------------------------------------------------------------------------
  1265. // T3DRadio::DoPostCreate
  1266. //----------------------------------------------------------------------------------------
  1267. #pragma segment A3DControlOpen
  1268.  
  1269. void T3DRadio::DoPostCreate (TDocument *itsDocument) // OVERRIDE
  1270. {
  1271.     VRect                    theRect;
  1272.     TDrawingEnvironment     *environment;
  1273.  
  1274.     Inherited::DoPostCreate (itsDocument);
  1275.  
  1276.     // If we have a drawing environment, use it!
  1277.     if (environment = this->GetDrawingEnvironment())
  1278.     {
  1279.         this->SetBackColor(environment->fBackgroundColor);
  1280.         this->InstallColor(environment->fForegroundColor, false);
  1281.     }
  1282.  
  1283.     // Center the button vertically
  1284.     this->ControlArea(theRect);
  1285.     long height = theRect.bottom - theRect.top;
  1286.     height -= 12;
  1287.     long top = height / 2;
  1288.     fDrawBox.top += top;
  1289.     fDrawBox.bottom += top;
  1290.  
  1291. } // T3DRadio::DoPostCreate
  1292.  
  1293. //----------------------------------------------------------------------------------------
  1294. // T3DRadio::I3DRadio
  1295. //----------------------------------------------------------------------------------------
  1296. #pragma segment A3DControlOpen
  1297.  
  1298. void T3DRadio::I3DRadio (TView* itsSuperView, const VPoint& itsLocation,
  1299.                                  const VPoint& itsSize, SizeDeterminer itsHSizeDet,
  1300.                                  SizeDeterminer itsVSizeDet, const CStr255& itsLabel,
  1301.                                  Boolean isTurnedOn)
  1302. {
  1303.     VRect                    theRect;
  1304.     TDrawingEnvironment     *environment;
  1305.  
  1306.     this->IRadio (itsSuperView, itsLocation, itsSize,
  1307.                   itsHSizeDet, itsVSizeDet, itsLabel, isTurnedOn);
  1308.  
  1309.     // If we have a drawing environment, use it!
  1310.     if (environment = this->GetDrawingEnvironment())
  1311.     {
  1312.         this->SetBackColor(environment->fBackgroundColor);
  1313.         this->InstallColor(environment->fForegroundColor, false);
  1314.     }
  1315.  
  1316.     // Center the button vertically
  1317.     this->ControlArea(theRect);
  1318.     long height = theRect.bottom - theRect.top;
  1319.     height -= 12;
  1320.     long top = height / 2;
  1321.     fDrawBox.top += top;
  1322.     fDrawBox.bottom += top;
  1323.  
  1324. } // T3DRadio::I3DRadio
  1325.  
  1326. //----------------------------------------------------------------------------------------
  1327. // T3DRadio::Clone
  1328. //----------------------------------------------------------------------------------------
  1329. #pragma segment A3DControlNonRes
  1330.  
  1331. TObject* T3DRadio::Clone ()                // OVERRIDE
  1332. {
  1333.     T3DRadio*    aClonedRadio = (T3DRadio *)(Inherited::Clone ());
  1334.  
  1335.     aClonedRadio->fBackColor = fBackColor;
  1336.     aClonedRadio->fForeColor = fForeColor;
  1337.  
  1338.     return aClonedRadio;
  1339.  
  1340. } // T3DRadio::Clone
  1341.  
  1342. //----------------------------------------------------------------------------------------
  1343. // T3DRadio::Free
  1344. //----------------------------------------------------------------------------------------
  1345. #pragma segment A3DControlClose
  1346.  
  1347. void T3DRadio::Free ()                    // OVERRIDE
  1348. {
  1349.     Inherited::Free ();
  1350.  
  1351. } // T3DRadio::Free
  1352.  
  1353. //----------------------------------------------------------------------------------------
  1354. // T3DRadio::Draw
  1355. //----------------------------------------------------------------------------------------
  1356. #pragma segment A3DControlRes
  1357.  
  1358. void T3DRadio::Draw (const VRect& /*area*/)
  1359. {
  1360.     VRect             theRect;
  1361.     CRect            qdArea;
  1362.     CStr255            label;
  1363.     CGraphicsState    rememberGState;
  1364.  
  1365.     this->ControlArea(theRect);
  1366.     this->ViewToQDRect(theRect, qdArea);
  1367.  
  1368.     this->DrawBox();
  1369.     this->DrawCheck();
  1370.  
  1371.     // Draw the button text 4 pixels to the right of the button
  1372.     this->GetText (label);
  1373.     CRect textBox = qdArea;
  1374.     textBox.left += (short) fDrawBox.right + 4;
  1375.     this->DrawBoxText (label, textBox, false);
  1376.  
  1377. } // T3DRadio::Draw
  1378.  
  1379. //----------------------------------------------------------------------------------------
  1380. // T3DButton::DoMouseCommand
  1381. //----------------------------------------------------------------------------------------
  1382. #pragma segment A3DControlSelCommand
  1383.  
  1384. void T3DRadio::DoMouseCommand(VPoint& theMouse,
  1385.                             TToolboxEvent* ,
  1386.                             CPoint)        // override
  1387. {
  1388.     TControlTracker * aControlTracker = new TControlTracker;
  1389.     aControlTracker->IControlTracker(this, theMouse);
  1390.     this->PostCommand(aControlTracker);
  1391. } // T3DRadio::DoMouseCommand
  1392.  
  1393. //----------------------------------------------------------------------------------------
  1394. // T3DRadio::TrackMouse
  1395. //----------------------------------------------------------------------------------------
  1396. #pragma segment A3DControlSelCommand
  1397.  
  1398. void T3DRadio::TrackMouse(TrackPhase aTrackPhase,
  1399.                          VPoint& ,
  1400.                          // anchorPoint
  1401.                          VPoint& ,
  1402.                          // previousPoint
  1403.                          VPoint& nextPoint,
  1404.                          Boolean)                            // OVERRIDE
  1405. {
  1406.     Boolean state = false;
  1407.  
  1408.     if (!this->IsDimmed())
  1409.     {
  1410.         switch(aTrackPhase)
  1411.         {
  1412.         case trackBegin:
  1413.             state = fHilite;
  1414.             this->HiliteState(true, kRedraw);
  1415.             break;
  1416.         case trackContinue:
  1417.             if (this->ContainsMouse(nextPoint))
  1418.                 this->HiliteState(true, kRedraw);
  1419.             else
  1420.                 this->HiliteState(state, kRedraw);
  1421.             break;
  1422.         case trackEnd:
  1423.             if (this->ContainsMouse(nextPoint))
  1424.             {
  1425.                 this->HiliteState(false, this->IsOn());
  1426.                 this->HandleEvent(fEventNumber, this, NULL);
  1427.             }
  1428.             break;
  1429.         }
  1430.     }
  1431. }    // T3DRadio::TrackMouse
  1432.  
  1433. //----------------------------------------------------------------------------------------
  1434. // T3DRadio::SetLongVal:
  1435. // Override the way the control works so that we don't call the CDEF
  1436. //----------------------------------------------------------------------------------------
  1437. #pragma segment A3DControlRes
  1438.  
  1439. void T3DRadio::SetLongVal(VCoordinate itsVal, Boolean /*redraw*/)
  1440. {
  1441.     itsVal = Max(fLongMin, Min(itsVal, fLongMax));
  1442.     if (itsVal != fLongVal)
  1443.     {
  1444.         fLongVal = itsVal;
  1445.         CRect tempRect;
  1446.         this->ViewToQDRect(fDrawBox, tempRect);
  1447.  
  1448.         // Make a region for the inside of the button to invalidate
  1449.         CTemporaryRegion    region;
  1450.         InsetRect(tempRect, 1,1);
  1451.         OpenRgn();
  1452.         FrameOval(tempRect);
  1453.         CloseRgn(region);
  1454.         this->InvalidateRegion(region);
  1455.     }
  1456. } // T3DRadio::SetLongVal
  1457.  
  1458. //----------------------------------------------------------------------------------------
  1459. // T3DRadio::HiliteState:
  1460. //----------------------------------------------------------------------------------------
  1461. #pragma segment A3DControlNonRes
  1462.  
  1463. void T3DRadio::HiliteState(Boolean state,Boolean redraw)
  1464. {
  1465.     if (state != fHilite)
  1466.     {
  1467.         fHilite = state;
  1468.         if (state)                                // hilite adorner draws the hilite state
  1469.             this->AddAdorner(gHiliteAdorner, kAdornLast - 5, kDontRedraw);
  1470.         else
  1471.             this->DeleteAdorner(gHiliteAdorner, kDontRedraw);
  1472.         if (redraw)
  1473.             this->Hilite();
  1474.     }
  1475. } // T3DRadio::HiliteState
  1476.  
  1477. //----------------------------------------------------------------------------------------
  1478. // T3DRadio::DimState:
  1479. //----------------------------------------------------------------------------------------
  1480. #pragma segment A3DControlNonRes
  1481.  
  1482. void T3DRadio::DimState(Boolean state, Boolean redraw)
  1483. {
  1484.     if (state != fDimmed)
  1485.     {
  1486.         fDimmed = state;
  1487.         if (state)                                // dim adorner draws the dim state
  1488.             this->AddAdorner(gDimAdorner, kAdornLast - 10, kDontRedraw);
  1489.         else
  1490.             this->DeleteAdorner(gDimAdorner, kDontRedraw);
  1491.         if (redraw)
  1492.             this->DrawContents();                // Draw change immediately
  1493.     }
  1494. } // T3DRadio::DimState
  1495.  
  1496. //----------------------------------------------------------------------------------------
  1497. // T3DRadio::Hilite
  1498. //----------------------------------------------------------------------------------------
  1499. #pragma segment A3DControlRes
  1500.  
  1501. void T3DRadio::Hilite ()        // OVERRIDE
  1502. {
  1503.     VRect            area;
  1504.     CRect            qdArea, qdBox;
  1505.     CGraphicsState    rememberGState;
  1506.  
  1507.     #if qDebug
  1508.         this->AssumeFocused ();
  1509.     #endif
  1510.  
  1511.     this->ControlArea (area);
  1512.     this->ViewToQDRect (area, qdArea);
  1513.     this->ViewToQDRect(fDrawBox, qdBox);
  1514.  
  1515.     CPenNormal();
  1516.     if (fHilite)
  1517.     {
  1518.         InsetRect(qdBox, 1, 1);
  1519.         FrameOval(qdBox);
  1520.         InsetRect(qdBox, 1,1);
  1521.  
  1522.         // Erase the content of the oval
  1523.         SetIfBkColor(fBackColor);
  1524.         if (this->IsOn())
  1525.         {
  1526.             PenPat(&qd.white);
  1527.             FrameOval(qdBox);
  1528.         }
  1529.         else
  1530.             EraseOval(qdBox);
  1531.     }
  1532.     else
  1533.         this->DrawCheck();
  1534. } // T3DRadio::Hilite
  1535.  
  1536. //----------------------------------------------------------------------------------------
  1537. // T3DRadio::Dim
  1538. //----------------------------------------------------------------------------------------
  1539. #pragma segment ControlRes
  1540.  
  1541. void T3DRadio::Dim ()        // OVERRIDE
  1542. {
  1543.     VRect             area;
  1544.     CRect             qdArea;
  1545.     CGraphicsState    rememberGState;
  1546.  
  1547.     this->ControlArea (area);
  1548.     area.left += fDrawBox.right;
  1549.     this->ViewToQDRect (area, qdArea);
  1550.  
  1551.     short pixelSize;
  1552.     CDrawPerDevice device(qdArea);
  1553.     while (device.NextDevice (pixelSize))
  1554.     {
  1555.         // Do the normal gray pattern thing if we're in B & W
  1556.         if (pixelSize < 2)
  1557.         {
  1558.             #if qDebug
  1559.                 this->AssumeFocused ();
  1560.             #endif
  1561.  
  1562.             InsetRect (qdArea, 1, 1);
  1563.  
  1564.             PenPat (&qd.gray);
  1565.             PenMode (patBic);
  1566.             PaintRect (qdArea);
  1567.             InsetRect (qdArea, -1, -1);
  1568.         }
  1569.     }
  1570. } // T3DRadio::Dim
  1571.  
  1572. //----------------------------------------------------------------------------------------
  1573. // T3DRadio::DrawBoxText
  1574. //----------------------------------------------------------------------------------------
  1575. #pragma segment A3DControlRes
  1576.  
  1577. void T3DRadio::DrawBoxText (const CStr255& s, const CRect& box, Boolean preferOutline)
  1578. {
  1579.     FontInfo         theFontInfo;
  1580.     CRect             localBox = box;
  1581.     CRect            qdArea;
  1582.     CGraphicsState    rememberGState;
  1583.  
  1584.     CWhileOutlinePreferred setOP (preferOutline);
  1585.  
  1586.     short textHeight = MAGetFontInfo (theFontInfo);
  1587.     CPoint boxSize = localBox.GetSize ();
  1588.  
  1589.     // Center the text horizontally
  1590.     localBox.top += (boxSize.v - textHeight) / 2;
  1591.     MoveTo (localBox.left, localBox.top + theFontInfo.ascent);
  1592.  
  1593.     short pixelSize;
  1594.     CDrawPerDevice device(localBox);
  1595.     while (device.NextDevice (pixelSize))
  1596.     {
  1597.         // If we're dimmed, draw in gray, else draw in the fore color
  1598.         if (pixelSize > 2)
  1599.         {
  1600.             SetIfBkColor(fBackColor);
  1601.             if (this->IsDimmed())
  1602.                 // Draw the text in gray if we can
  1603.                 SetIfColor(kMediumGray);
  1604.             else
  1605.                 SetIfColor(fForeColor);
  1606.         }
  1607.         MoveTo (localBox.left, localBox.top + theFontInfo.ascent);
  1608.         DrawString (s);        // This would be faster if we did StringWidth and DrawChar...
  1609.     }
  1610.  
  1611. } // T3DRadio::DrawBoxText
  1612.  
  1613. //----------------------------------------------------------------------------------------
  1614. // T3DRadio::DrawBox
  1615. //----------------------------------------------------------------------------------------
  1616. #pragma segment A3DControlRes
  1617.  
  1618. void T3DRadio::DrawBox()
  1619. {
  1620.     CRect            qdBox;
  1621.     CGraphicsState    rememberGState;
  1622.  
  1623.     this->ViewToQDRect(fDrawBox, qdBox);
  1624.  
  1625.     short pixelSize;
  1626.     CDrawPerDevice device(qdBox);
  1627.     while (device.NextDevice (pixelSize))
  1628.     {
  1629.         if (pixelSize > 2)
  1630.         {
  1631.             if (this->IsDimmed())
  1632.                 SetIfColor(kMediumGray);
  1633.             else
  1634.                 SetIfColor(fForeColor);
  1635.         }
  1636.         FrameOval(qdBox);
  1637.     }
  1638. }
  1639.  
  1640. //----------------------------------------------------------------------------------------
  1641. // T3DRadio::DrawCheck
  1642. // This actually draws a dot, but I wanted to keep it similar to the check box
  1643. //----------------------------------------------------------------------------------------
  1644. #pragma segment A3DControlRes
  1645.  
  1646. void T3DRadio::DrawCheck()
  1647. {
  1648.     CRect            qdBox;
  1649.     short            pixelSize;
  1650.     CGraphicsState    rememberGState;
  1651.  
  1652.     this->ViewToQDRect(fDrawBox, qdBox);
  1653.  
  1654.     // First erase the oval
  1655.     InsetRect(qdBox, 1, 1);
  1656.     if (this->IsDimmed())
  1657.         SetIfBkColor(fBackColor);
  1658.     else
  1659.         SetIfBkColor(gRGBWhite);
  1660.     EraseOval(qdBox);
  1661.     InsetRect(qdBox, -1, -1);
  1662.  
  1663.     // Check to see if we're on
  1664.     if (this->IsOn())
  1665.     {
  1666.         CDrawPerDevice device(qdBox);
  1667.         while (device.NextDevice (pixelSize))
  1668.         {
  1669.             // This takes some pretty subtle work
  1670.             if (pixelSize > 2)
  1671.             {
  1672.                 if (!this->IsDimmed())
  1673.                 {
  1674.                     SetIfColor(kLightGray);
  1675.                     MoveTo(qdBox.left + 9, qdBox.top + 5);
  1676.                     LineTo(qdBox.left + 9, qdBox.top + 7);
  1677.                     MoveTo(qdBox.left + 5, qdBox.top + 9);
  1678.                     LineTo(qdBox.left + 7, qdBox.top + 9);
  1679.  
  1680.                     SetIfColor(kLightGray2);
  1681.                     MoveTo(qdBox.left + 3, qdBox.top + 9);
  1682.                     LineTo(qdBox.left + 4, qdBox.top + 9);
  1683.                     MoveTo(qdBox.left + 9, qdBox.top + 3);
  1684.                     LineTo(qdBox.left + 9, qdBox.top + 4);
  1685.  
  1686.                     SetIfColor(kLightGray4);
  1687.                     MoveTo(qdBox.left + 2, qdBox.top + 9);
  1688.                     LineTo(qdBox.left + 2, qdBox.top + 8);
  1689.                     LineTo(qdBox.left + 3, qdBox.top + 8);
  1690.                     MoveTo(qdBox.left + 8, qdBox.top + 3);
  1691.                     LineTo(qdBox.left + 8, qdBox.top + 2);
  1692.                     LineTo(qdBox.left + 9, qdBox.top + 2);
  1693.  
  1694.                     SetIfColor(kMediumLightGray);
  1695.                     MoveTo(qdBox.left + 2, qdBox.top + 7);
  1696.                     LineTo(qdBox.left + 2, qdBox.top + 4);
  1697.                     LineTo(qdBox.left + 4, qdBox.top + 2);
  1698.                     LineTo(qdBox.left + 7, qdBox.top + 2);
  1699.  
  1700.                     SetIfColor(kMediumGray);
  1701.                     MoveTo(qdBox.left + 1, qdBox.top + 7);
  1702.                     LineTo(qdBox.left + 1, qdBox.top + 4);
  1703.                     LineTo(qdBox.left + 4, qdBox.top + 1);
  1704.                     LineTo(qdBox.left + 7, qdBox.top + 1);
  1705.                     MoveTo(qdBox.left + 2, qdBox.top + 2); // this is faster
  1706.                     LineTo(qdBox.left + 2, qdBox.top + 2); // than SetCPixel
  1707.                     SetIfColor(gRGBBlack);
  1708.                 }
  1709.                 else
  1710.                     SetIfColor(kMediumGray);
  1711.             }
  1712.             else
  1713.                 SetIfColor(gRGBBlack);
  1714.             InsetRect(qdBox, 3,3);
  1715.             FillOval(qdBox, &qd.black);
  1716.             InsetRect(qdBox, -3, -3);
  1717.         }
  1718.     }
  1719.     // This is how we look when we're off
  1720.     else
  1721.     {
  1722.         // Off and dimmed takes some work, off and not dimmed takes no work
  1723.         if (!this->IsDimmed())
  1724.         {
  1725.             CDrawPerDevice device(qdBox);
  1726.             while (device.NextDevice (pixelSize))
  1727.             {
  1728.                 if (pixelSize > 2)
  1729.                 {
  1730.                     SetIfColor(kLightGray);
  1731.                     MoveTo(qdBox.left + 6, qdBox.top + 2);
  1732.                     LineTo(qdBox.left + 3, qdBox.top + 5);
  1733.                     MoveTo(qdBox.left + 4, qdBox.top + 5);
  1734.                     LineTo(qdBox.left + 7, qdBox.top + 2);
  1735.                     MoveTo(qdBox.left + 3, qdBox.top + 5);
  1736.                     LineTo(qdBox.left + 3, qdBox.top + 7);
  1737.  
  1738.                     SetIfColor(kLightGray2);
  1739.                     MoveTo(qdBox.left + 3, qdBox.top + 8);
  1740.                     LineTo(qdBox.left + 4, qdBox.top + 8);
  1741.                     LineTo(qdBox.left + 4, qdBox.top + 6);
  1742.                     LineTo(qdBox.left + 6, qdBox.top + 6);
  1743.                     LineTo(qdBox.left + 6, qdBox.top + 4);
  1744.                     LineTo(qdBox.left + 7, qdBox.top + 4);
  1745.                     LineTo(qdBox.left + 7, qdBox.top + 3);
  1746.                     LineTo(qdBox.left + 8, qdBox.top + 3);
  1747.                     LineTo(qdBox.left + 8, qdBox.top + 2);
  1748.                     MoveTo(qdBox.left + 5, qdBox.top + 5);
  1749.                     LineTo(qdBox.left + 5, qdBox.top + 5);
  1750.                     MoveTo(qdBox.left + 7, qdBox.top + 5);
  1751.                     LineTo(qdBox.left + 7, qdBox.top + 5);
  1752.                     MoveTo(qdBox.left + 5, qdBox.top + 7);
  1753.                     LineTo(qdBox.left + 5, qdBox.top + 7);
  1754.  
  1755.                     SetIfColor(kLightGray4);
  1756.                     MoveTo(qdBox.left + 3, qdBox.top + 9);
  1757.                     LineTo(qdBox.left + 5, qdBox.top + 9);
  1758.                     LineTo(qdBox.left + 5, qdBox.top + 8);
  1759.                     LineTo(qdBox.left + 6, qdBox.top + 8);
  1760.                     LineTo(qdBox.left + 6, qdBox.top + 7);
  1761.                     LineTo(qdBox.left + 7, qdBox.top + 7);
  1762.                     LineTo(qdBox.left + 7, qdBox.top + 6);
  1763.                     LineTo(qdBox.left + 8, qdBox.top + 6);
  1764.                     LineTo(qdBox.left + 8, qdBox.top + 4);
  1765.  
  1766.                     SetIfColor(kMediumLightGray);
  1767.                     MoveTo(qdBox.left + 6, qdBox.top + 9);
  1768.                     LineTo(qdBox.left + 7, qdBox.top + 9);
  1769.                     LineTo(qdBox.left + 7, qdBox.top + 8);
  1770.                     LineTo(qdBox.left + 8, qdBox.top + 8);
  1771.                     LineTo(qdBox.left + 8, qdBox.top + 7);
  1772.                     LineTo(qdBox.left + 9, qdBox.top + 7);
  1773.                     LineTo(qdBox.left + 9, qdBox.top + 2);
  1774.  
  1775.                     SetIfColor(kMediumGray);
  1776.                     MoveTo(qdBox.left + 4, qdBox.top + 10);
  1777.                     LineTo(qdBox.left + 7, qdBox.top + 10);
  1778.                     MoveTo(qdBox.left + 8, qdBox.top + 9);
  1779.                     LineTo(qdBox.left + 9, qdBox.top + 9);
  1780.                     LineTo(qdBox.left + 9, qdBox.top + 8);
  1781.                     MoveTo(qdBox.left + 10, qdBox.top + 7);
  1782.                     LineTo(qdBox.left + 10, qdBox.top + 4);
  1783.  
  1784.                 }
  1785.             }
  1786.         }
  1787.     }
  1788. }
  1789.  
  1790. //----------------------------------------------------------------------------------------
  1791. // T3DRadio::InstallColor
  1792. // Override because we don't want the Inherited method, which uses the CDEF
  1793. //----------------------------------------------------------------------------------------
  1794. #pragma segment A3DControlRes
  1795.  
  1796. void T3DRadio::InstallColor(const CRGBColor& theColor, Boolean redraw)
  1797. {
  1798.     fForeColor = theColor;
  1799.     if (redraw)
  1800.         this->ForceRedraw();
  1801. }
  1802.  
  1803. //----------------------------------------------------------------------------------------
  1804. // CLASS:    T3DButton
  1805. // A 3D version of our old friend the Button
  1806. //----------------------------------------------------------------------------------------
  1807.  
  1808. //----------------------------------------------------------------------------------------
  1809. // T3DButton::Initialize
  1810. //----------------------------------------------------------------------------------------
  1811. #pragma segment A3DControlOpen
  1812.  
  1813. #undef Inherited
  1814. #define Inherited TButton
  1815. DefineClass(T3DButton, Inherited);
  1816.  
  1817. void T3DButton::Initialize ()                // OVERRIDE
  1818. {
  1819.     f3DAdorner = NULL;
  1820.     fHilitedTextColor = gRGBBlack;
  1821.  
  1822. } // T3DButton::Initialize
  1823.  
  1824. //----------------------------------------------------------------------------------------
  1825. // T3DButton::DoPostCreate
  1826. //----------------------------------------------------------------------------------------
  1827. #pragma segment A3DControlOpen
  1828.  
  1829. void T3DButton::DoPostCreate (TDocument *itsDocument) // OVERRIDE
  1830. {
  1831.     Inherited::DoPostCreate (itsDocument);
  1832.  
  1833.     if (f3DAdorner == NULL)
  1834.         this->CreateButtonAdorner ();
  1835.  
  1836. } // T3DButton::DoPostCreate
  1837.  
  1838. //----------------------------------------------------------------------------------------
  1839. // T3DButton::I3DButton
  1840. //----------------------------------------------------------------------------------------
  1841. #pragma segment A3DControlOpen
  1842.  
  1843. void T3DButton::I3DButton (TView* itsSuperView,
  1844.                             const VPoint& itsLocation,
  1845.                             const VPoint& itsSize,
  1846.                             SizeDeterminer itsHSizeDet,
  1847.                             SizeDeterminer itsVSizeDet,
  1848.                             const CStr255& itsLabel)
  1849. {
  1850.     this->IButton(itsSuperView, itsLocation, itsSize, itsHSizeDet, itsVSizeDet, itsLabel);
  1851.  
  1852.     // • If we are being built procedurally then build the adorner
  1853.     if (f3DAdorner == NULL)
  1854.         this->CreateButtonAdorner ();
  1855.  
  1856. } // T3DButton::I3DButton
  1857.  
  1858. //----------------------------------------------------------------------------------------
  1859. // T3DButton::Clone
  1860. //----------------------------------------------------------------------------------------
  1861. #pragma segment A3DControlNonRes
  1862.  
  1863. TObject* T3DButton::Clone ()                // OVERRIDE
  1864. {
  1865.     T3DButton*    aClonedButton = (T3DButton *)(Inherited::Clone ());
  1866.     aClonedButton->fHilitedTextColor = fHilitedTextColor;
  1867.     aClonedButton->CreateButtonAdorner();
  1868.  
  1869.     return aClonedButton;
  1870.  
  1871. } // T3DButton::Clone
  1872.  
  1873. //----------------------------------------------------------------------------------------
  1874. // T3DButton::Free
  1875. //----------------------------------------------------------------------------------------
  1876. #pragma segment A3DControlClose
  1877.  
  1878. void T3DButton::Free ()                    // OVERRIDE
  1879. {
  1880.     Inherited::Free ();
  1881.  
  1882. } // T3DButton::Free
  1883.  
  1884. //----------------------------------------------------------------------------------------
  1885. // T3DButton::DoMouseCommand
  1886. //----------------------------------------------------------------------------------------
  1887. #pragma segment A3DControlRes
  1888.  
  1889. void T3DButton::DoMouseCommand(VPoint& theMouse,
  1890.                                 TToolboxEvent* ,
  1891.                                 CPoint)        // override
  1892. {
  1893.     TControlTracker * aControlTracker = new TControlTracker;
  1894.     aControlTracker->IControlTracker(this, theMouse);
  1895.     this->PostCommand(aControlTracker);
  1896. } // TControl::DoMouseCommand
  1897.  
  1898. //----------------------------------------------------------------------------------------
  1899. // T3DButton::TrackMouse
  1900. //----------------------------------------------------------------------------------------
  1901. #pragma segment A3DControlSelCommand
  1902.  
  1903. void T3DButton::TrackMouse(TrackPhase aTrackPhase,
  1904.                              VPoint& ,
  1905.                              // anchorPoint
  1906.                              VPoint& ,
  1907.                              // previousPoint
  1908.                              VPoint& nextPoint,
  1909.                              Boolean)                            // OVERRIDE
  1910. {
  1911.     Boolean state = false;
  1912.  
  1913.     if (!this->IsDimmed())
  1914.     {
  1915.         switch(aTrackPhase)
  1916.         {
  1917.         case trackBegin:
  1918.             state = fHilite;
  1919.             this->HiliteState(true, kRedraw);
  1920.             break;
  1921.         case trackContinue:
  1922.             if (this->ContainsMouse(nextPoint))
  1923.                 this->HiliteState(true, kRedraw);
  1924.             else
  1925.                 this->HiliteState(state, kRedraw);
  1926.             break;
  1927.         case trackEnd:
  1928.             if (this->ContainsMouse(nextPoint))
  1929.             {
  1930.                 this->HiliteState(false, kRedraw);
  1931.                 this->HandleEvent(fEventNumber, this, NULL);
  1932.             }
  1933.             break;
  1934.         }
  1935.     }
  1936. }    // T3DButton::TrackMouse
  1937.  
  1938. //----------------------------------------------------------------------------------------
  1939. // T3DButton::HiliteState:
  1940. //----------------------------------------------------------------------------------------
  1941. #pragma segment A3DControlNonRes
  1942.  
  1943. void T3DButton::HiliteState(Boolean state,Boolean redraw)
  1944. {
  1945.     if (state != fHilite)
  1946.     {
  1947.         fHilite = state;
  1948.         if (state)                                // hilite adorner draws the hilite state
  1949.             this->AddAdorner(gHiliteAdorner, kAdornLast - 5, kDontRedraw);
  1950.         else
  1951.             this->DeleteAdorner(gHiliteAdorner, kDontRedraw);
  1952.         if (redraw && this->IsDrawable())
  1953.             this->Hilite();
  1954.     }
  1955. } // T3DButton::HiliteState
  1956.  
  1957. //----------------------------------------------------------------------------------------
  1958. // T3DButton::DimState:
  1959. //----------------------------------------------------------------------------------------
  1960. #pragma segment A3DControlNonRes
  1961.  
  1962. void T3DButton::DimState(Boolean state, Boolean redraw)
  1963. {
  1964.     if (state != fDimmed)
  1965.     {
  1966.         fDimmed = state;
  1967.         if (state)                                // dim adorner draws the dim state
  1968.             this->AddAdorner(gDimAdorner, kAdornLast - 10, kDontRedraw);
  1969.         else
  1970.             this->DeleteAdorner(gDimAdorner, kDontRedraw);
  1971.         if (redraw)
  1972.             this->DrawContents();                // Draw change immediately
  1973.     }
  1974. } // T3DButton::DimState
  1975.  
  1976. //----------------------------------------------------------------------------------------
  1977. // T3DButton::CreateButtonAdorner
  1978. //----------------------------------------------------------------------------------------
  1979. #pragma segment A3DControlOpen
  1980.  
  1981. void T3DButton::CreateButtonAdorner ()
  1982. {
  1983.     // • Add the Button Adorner
  1984.     T3DTextButtonAdorner* adorner = new T3DTextButtonAdorner;
  1985.     adorner->I3DTextButtonAdorner (kFreeOnDeletion);
  1986.     f3DAdorner = adorner;
  1987.  
  1988.     this->AddAdorner (adorner, kAdornFirst, kDontInvalidate);
  1989.  
  1990. } // T3DButton::CreateButtonAdorner
  1991.  
  1992. //----------------------------------------------------------------------------------------
  1993. // T3DButton::DrawBoxText
  1994. //----------------------------------------------------------------------------------------
  1995. #pragma segment A3DControlRes
  1996.  
  1997. void T3DButton::DrawBoxText (    const CStr255& s,
  1998.                                 const CRect& box,
  1999.                                 Boolean preferOutline)
  2000. {
  2001.     FontInfo     theFontInfo;
  2002.     CRect         qdArea, localBox = box;
  2003.     CGraphicsState    remember;
  2004.  
  2005.     CWhileOutlinePreferred setOP (preferOutline);
  2006.  
  2007.     short textHeight = MAGetFontInfo (theFontInfo);
  2008.     CPoint boxSize = localBox.GetSize ();
  2009.  
  2010.     // Center the text in the button
  2011.     localBox.left += (boxSize.h - StringWidth (s)) / 2;
  2012.     localBox.top += (boxSize.v - textHeight) / 2;
  2013.  
  2014.     this->ViewToQDRect (localBox, qdArea);
  2015.     short    pixelSize;
  2016.     CDrawPerDevice device(qdArea);
  2017.     while (device.NextDevice (pixelSize))
  2018.     {
  2019.         if (pixelSize >= 4)
  2020.         {
  2021.         // If we're non B & W and we're dimmed, draw in gray text
  2022.             if (this->IsDimmed())
  2023.                 SetIfColor(kMediumGray);
  2024.         // If we're hilited, use the hilite text color
  2025.             else if (fHilite)
  2026.                 SetIfColor(fHilitedTextColor);
  2027.         }
  2028.         MoveTo (localBox.left, localBox.top + theFontInfo.ascent);
  2029.         DrawString (s);
  2030.     }
  2031.  
  2032. } // T3DButton::DrawBoxText
  2033.  
  2034. //----------------------------------------------------------------------------------------
  2035. // T3DButton::Draw
  2036. //----------------------------------------------------------------------------------------
  2037. #pragma segment A3DControlRes
  2038.  
  2039. void T3DButton::Draw (const VRect& /*area*/)        // OVERRIDE
  2040. {
  2041.     VRect         theRect;
  2042.     CRect        qdArea;
  2043.     CStr255        label;
  2044.  
  2045.     this->ControlArea (theRect);
  2046.     this->ViewToQDRect (theRect, qdArea);
  2047.  
  2048.     this->GetText (label);
  2049.  
  2050.     // Just draw the text.  The adorner takes care of the 3D stuff
  2051.     DrawBoxText (label, qdArea, false);
  2052.  
  2053. } // T3DButton::Draw
  2054.  
  2055. //----------------------------------------------------------------------------------------
  2056. // T3DButton::Hilite
  2057. //----------------------------------------------------------------------------------------
  2058. #pragma segment ControlRes
  2059.  
  2060. void T3DButton::Hilite ()        // OVERRIDE
  2061. {
  2062.     VRect            area;
  2063.     CRect            qdArea;
  2064.     CGraphicsState    rememberGState;
  2065.  
  2066. #if qDebug
  2067.     this->AssumeFocused ();
  2068. #endif
  2069.  
  2070.     this->ControlArea (area);
  2071.     this->ViewToQDRect (area, qdArea);
  2072.  
  2073.     short    pixelSize;
  2074.     CDrawPerDevice device(qdArea);
  2075.     // We use some funky logic here because of the way the 3d adorner works.
  2076.     // For 4, 8 and above, we draw one way.  Otherwise we draw another way
  2077.     // See the adorner code for more info
  2078.     while (device.NextDevice (pixelSize))
  2079.     {
  2080.         if (pixelSize < 4)
  2081.         {
  2082.             // We need to draw the text BEFORE the adorner if we're B & W
  2083.             if (fHilite)
  2084.             {
  2085.                 this->Draw (area);
  2086.                 f3DAdorner->Draw (this, area);
  2087.             }
  2088.             else
  2089.             {
  2090.                 f3DAdorner->Draw(this, area);
  2091.                 this->Draw(area);
  2092.             }
  2093.         }
  2094.         else
  2095.         {
  2096.             // We need to draw the text AFTER the adorner for better than B & W
  2097.             f3DAdorner->Draw(this, area);
  2098.             this->Draw(area);
  2099.         }
  2100.     }
  2101. } // T3DButton::Hilite
  2102.  
  2103. //----------------------------------------------------------------------------------------
  2104. // T3DButton::Dim
  2105. //----------------------------------------------------------------------------------------
  2106. #pragma segment A3DControlRes
  2107.  
  2108. void T3DButton::Dim ()        // OVERRIDE
  2109. {
  2110.     VRect            area;
  2111.     CRect            qdArea;
  2112.     CGraphicsState     rememberGState;
  2113.  
  2114. #if qDebug
  2115.     this->AssumeFocused ();
  2116. #endif
  2117.  
  2118.     this->ControlArea (area);
  2119.     this->ViewToQDRect (area, qdArea);
  2120.     InsetRect (qdArea, 1, 1);
  2121.  
  2122.     short pixelSize;
  2123.     CDrawPerDevice device(qdArea);
  2124.     while (device.NextDevice (pixelSize))
  2125.     {
  2126.         // The old fashioned way is to use a gray pattern to dim
  2127.         if (pixelSize < 2)
  2128.         {
  2129.             #if qDebug
  2130.                 this->AssumeFocused ();
  2131.             #endif
  2132.  
  2133.             InsetRect (qdArea, 1, 1);
  2134.  
  2135.             PenPat (&qd.gray);
  2136.             PenMode (patBic);
  2137.             PaintRect (qdArea);
  2138.             InsetRect (qdArea, -1, -1);
  2139.         }
  2140.     }
  2141.  
  2142. } // T3DButton::Dim
  2143.  
  2144. //----------------------------------------------------------------------------------------
  2145. // T3DTextButtonAdorner
  2146. // This is an auxiliary adorner for T3DButtons
  2147. //----------------------------------------------------------------------------------------
  2148.  
  2149. //----------------------------------------------------------------------------------------
  2150. // T3DTextButtonAdorner::I3DTextButtonAdorner
  2151. //----------------------------------------------------------------------------------------
  2152. #pragma segment A3DControlOpen
  2153.  
  2154. #undef Inherited
  2155. #define Inherited TAdorner
  2156. DefineClass(T3DTextButtonAdorner, Inherited);
  2157.  
  2158. void T3DTextButtonAdorner::I3DTextButtonAdorner (    Boolean freeOnDeletion)
  2159. {
  2160.     // • Call our superclass to complete initialization
  2161.     this->IAdorner (k3DTextButtonAdorner,freeOnDeletion);
  2162.  
  2163. } // T3DTextButtonAdorner::I3DTextButtonAdorner
  2164.  
  2165. //----------------------------------------------------------------------------------------
  2166. // •• DRAWING
  2167. //----------------------------------------------------------------------------------------
  2168. // T3DTextButtonAdorner::Draw
  2169. //----------------------------------------------------------------------------------------
  2170. //
  2171. // This overridden draw method handles the drawing of the buttons border and then
  2172. // branches to the appropriate appropriate method to draw the buttons contents, based
  2173. // on the bit depth of the device being drawn to.  Currently this method supports 1, 4,
  2174. // and 8 bit or more devices.
  2175.  
  2176. #pragma segment A3DControlRes
  2177.  
  2178. void T3DTextButtonAdorner::Draw ( TView* itsView, const VRect& /*area*/)
  2179. {
  2180.     VRect                theRect;
  2181.     CRect                qdArea;
  2182.     short                pixelSize;
  2183.     CRGBColor            color;
  2184.  
  2185.     // • Instantiate a stack based object that saves our graphic state
  2186.     CGraphicsState aGraphicsState;
  2187.  
  2188.     // • Coerce the view to a control and then get its QD area
  2189.     TControl* theControl = (TControl*)itsView;
  2190.     theControl->ControlArea (theRect);
  2191.     theControl->ViewToQDRect (theRect, qdArea);
  2192.  
  2193.     // • Instantiate the stack based object that handles the per device clipping
  2194.     // the area is passed in so that the object can do clipping from it
  2195.     CDrawPerDevice device (qdArea);
  2196.  
  2197.     // • We will cycle through all of the devices, drawing will be handle based on
  2198.     // the pixel size for each device
  2199.     while (device.NextDevice (pixelSize))
  2200.     {
  2201.  
  2202.         // • Draw the button with full colors
  2203.         if (pixelSize >= 8)
  2204.         {
  2205.             // • First step is to setup the appropriate gray fill color
  2206.             if (theControl->fHilite)
  2207.                 color = kMediumGray;
  2208.             else if (((TButton *)itsView)->IsDimmed())
  2209.                 color = kLightGray;
  2210.             else
  2211.                 color = kLightGray2;
  2212.  
  2213.             // • Fill the round rect with the color
  2214.             SetIfColor (color);
  2215.             PaintRoundRect (qdArea, kOvalWidth, kOvalHeight);
  2216.  
  2217.             // • Frame button with a black border or gray if it's dimmed
  2218.             if (((TButton *)itsView)->IsDimmed())
  2219.                 SetIfColor(kMediumGray);
  2220.             else
  2221.                 SetIfColor (gRGBBlack);
  2222.             this->Frame (qdArea);
  2223.  
  2224.             // • Inset the area in preparartion for the drawing of the buttons content
  2225.             InsetRect (qdArea, 1, 1);
  2226.  
  2227.             // • Draw the button assuming 8 bit or better color
  2228.             // But don't draw any 3D if we're dimmed
  2229.             if (!((TButton *)itsView)->IsDimmed())
  2230.                 this->Draw8Bit (qdArea, theControl->fHilite);
  2231.  
  2232.             InsetRect (qdArea, -1, -1);
  2233.  
  2234.         }
  2235.         else if (pixelSize == 4)    // • Draw with only 16 colors
  2236.         {
  2237.  
  2238.             // • First step is to setup the appropriate gray fill color
  2239.             if (theControl->fHilite)
  2240.                 SetRGBColor (color, kRGB4BitGray2, kRGB4BitGray2, kRGB4BitGray2);
  2241.             else if (((TButton *)itsView)->IsDimmed())
  2242.                 color = kLightGray;
  2243.             else
  2244.                 SetRGBColor (color, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1);
  2245.  
  2246.             // • Fill the round rect with the color
  2247.             SetIfColor (color);
  2248.             PaintRoundRect (qdArea, kOvalWidth, kOvalHeight);
  2249.  
  2250.             // • Frame button with a black border or gray if we're dimmed
  2251.             if (((TButton *)itsView)->IsDimmed())
  2252.                 SetIfColor(kMediumGray);
  2253.             else
  2254.                 SetIfColor (gRGBBlack);
  2255.             this->Frame (qdArea);
  2256.  
  2257.             // • Inset the area in preparartion for the drawing of the buttons content
  2258.             InsetRect (qdArea, 1, 1);
  2259.  
  2260.             // • For now we will draw the 1 bit style for 4 bit, but this should be
  2261.             // replaced with a 4 bit algorithm which will give you 3 shades of gray
  2262.             // But don't draw any 3D if we're dimmed
  2263.             if (!((TButton *)itsView)->IsDimmed())
  2264.                 this->Draw4Bit (qdArea, theControl->fHilite);
  2265.  
  2266.             InsetRect (qdArea, -1, -1);
  2267.  
  2268.         }
  2269.         else if (pixelSize < 4)    // • Draw with 4 colors or less (no grays)
  2270.         {
  2271.             // • We are hiliting so we need to invert the whole thing
  2272.             if  (theControl->fHilite)
  2273.             {
  2274.                 // • First we paint the inside white
  2275.                 InvertRoundRect (qdArea, kOvalWidth, kOvalHeight);
  2276.  
  2277.                 // • Frame button with a black border
  2278.                 SetIfColor (gRGBBlack);
  2279.                 this->Frame (qdArea);
  2280.             }
  2281.             else
  2282.             {
  2283.                 // • First we erase the entire area
  2284.                 SetIfBkColor (gRGBWhite);
  2285.                 EraseRoundRect (qdArea, kOvalWidth, kOvalHeight);
  2286.  
  2287.                 // • Frame button with a black border
  2288.                 SetIfColor (gRGBBlack);
  2289.                 this->Frame (qdArea);
  2290.             }
  2291.         }
  2292.     }
  2293.  
  2294. } // T3DTextButtonAdorner::Draw
  2295.  
  2296. //----------------------------------------------------------------------------------------
  2297. // •• PRIVATE DRAWING
  2298. //----------------------------------------------------------------------------------------
  2299. // T3DTextButtonAdorner::Draw8Bit
  2300. //----------------------------------------------------------------------------------------
  2301. #pragma segment A3DControlRes
  2302.  
  2303. void T3DTextButtonAdorner::Draw8Bit (const CRect& rect, Boolean hilite)
  2304. {
  2305.     CRect             insetArea;
  2306.     CRect             controlArea;
  2307.     CRGBColor         color;
  2308.     CRGBColor         light;
  2309.     CRGBColor         dark;
  2310.  
  2311.     // • Make a copy of the rect passed in
  2312.     controlArea = rect;
  2313.  
  2314.     // • Save off the area passed in
  2315.     insetArea = rect;
  2316.  
  2317.     // • Draw the hilited button
  2318.     if (hilite)
  2319.     {
  2320.         // • Outside edge of left top shadow
  2321.         SetRGBColor (color, kRGB8BitGray9, kRGB8BitGray9, kRGB8BitGray9);
  2322.         SetIfColor (color);
  2323.         MoveTo (controlArea.left, controlArea.bottom - 3);
  2324.         LineTo (controlArea.left, controlArea.top + 2);
  2325.         MoveTo (controlArea.left + 2, controlArea.top);
  2326.         LineTo (controlArea.right - 3, controlArea.top);
  2327.  
  2328.         // • Outside edge of bottom right shadow
  2329.         SetRGBColor (color, kRGB8BitGray3, kRGB8BitGray3, kRGB8BitGray3);
  2330.         SetIfColor (color);
  2331.         MoveTo (controlArea.left + 2, controlArea.bottom - 1);
  2332.         LineTo (controlArea.right - 3, controlArea.bottom - 1);
  2333.         MoveTo (controlArea.right - 1, controlArea.bottom - 3);
  2334.         LineTo (controlArea.right - 1, controlArea.top + 2);
  2335.  
  2336.         // • Inset our rectangle as we move to the next level
  2337.         InsetRect (controlArea, 1, 1);
  2338.  
  2339.         // • Inside edge of left top shadow
  2340.         SetRGBColor (color, kRGB8BitGray8, kRGB8BitGray8, kRGB8BitGray8);
  2341.         SetIfColor (color);
  2342.         MoveTo (controlArea.left, controlArea.bottom - 2);
  2343.         LineTo (controlArea.left, controlArea.top + 1);
  2344.         MoveTo (controlArea.left + 1, controlArea.top);
  2345.         LineTo (controlArea.right - 2, controlArea.top);
  2346.  
  2347.         // • Inside edge of bottom right shadow
  2348.         color = kMediumLightGray;
  2349.         SetIfColor (color);
  2350.         MoveTo (controlArea.left + 1, controlArea.bottom - 1);
  2351.         LineTo (controlArea.right - 2, controlArea.bottom - 1);
  2352.         MoveTo (controlArea.right - 1, controlArea.bottom - 2);
  2353.         LineTo (controlArea.right - 1, controlArea.top + 1);
  2354.  
  2355.         // •• Now draw the corners
  2356.         // • TopLeft 1
  2357.         SetRGBColor (light, kRGB8BitGray8, kRGB8BitGray8, kRGB8BitGray8);
  2358.         SetRGBColor (dark, kRGB8BitGray9, kRGB8BitGray9, kRGB8BitGray9);
  2359.         this->TopLeftCorner (insetArea, light, dark, hilite);
  2360.  
  2361.         // • TopRight 2
  2362.         SetRGBColor (light, kRGB8BitGray8, kRGB8BitGray8, kRGB8BitGray8);
  2363.         SetRGBColor (dark, kRGB8BitGray9, kRGB8BitGray9, kRGB8BitGray9);
  2364.         this->TopRightCorner (insetArea, light, dark, hilite);
  2365.  
  2366.         // • BotLeft 3
  2367.         // • Colors same as previous corner
  2368.         this->BotLeftCorner (insetArea, light, dark, hilite);
  2369.  
  2370.         // • BotRight 4
  2371.         SetRGBColor (light, kRGB8BitGray3, kRGB8BitGray3, kRGB8BitGray3);
  2372.         dark = kMediumLightGray;
  2373.         this->BotRightCorner (insetArea, light, dark, hilite);
  2374.  
  2375.     }
  2376.     else // • Draw the unhilited button
  2377.     {
  2378.         // • Outside edge of bottom right shadow
  2379.         SetRGBColor (color, kRGB8BitGray8, kRGB8BitGray8, kRGB8BitGray8);
  2380.         SetIfColor (color);
  2381.         MoveTo (controlArea.left + 2, controlArea.bottom - 1);
  2382.         LineTo (controlArea.right - 3, controlArea.bottom - 1);
  2383.         MoveTo (controlArea.right - 1, controlArea.bottom - 3);
  2384.         LineTo (controlArea.right - 1, controlArea.top + 2);
  2385.  
  2386.         // • Inset our rectangle as we move to the next level
  2387.         InsetRect (controlArea, 1, 1);
  2388.  
  2389.         // • Light on edge of button - light source edge
  2390.         SetIfColor (gRGBWhite);
  2391.         MoveTo (controlArea.left, controlArea.bottom - 2);
  2392.         LineTo (controlArea.left, controlArea.top + 1);
  2393.         MoveTo (controlArea.left + 1, controlArea.top);
  2394.         LineTo (controlArea.right - 2, controlArea.top);
  2395.  
  2396.         // • Inside edge of bottom right shadow
  2397.         color = kMediumGray;
  2398.         SetIfColor (color);
  2399.         MoveTo (controlArea.left + 1, controlArea.bottom - 1);
  2400.         LineTo (controlArea.right - 2, controlArea.bottom - 1);
  2401.         MoveTo (controlArea.right - 1, controlArea.bottom - 2);
  2402.         LineTo (controlArea.right - 1, controlArea.top + 1);
  2403.  
  2404.         // •• Now draw the corners
  2405.         // • TopLeft 1
  2406.         this->TopLeftCorner (insetArea, gRGBWhite, gRGBWhite, hilite);
  2407.  
  2408.         // • TopRight 2
  2409.         light = kLightGray4;
  2410.         this->TopRightCorner (insetArea, light, light, hilite);
  2411.  
  2412.         // • BotLeft 3
  2413.         // • Colors same as previous corner
  2414.         this->BotLeftCorner (insetArea, light, light, hilite);
  2415.  
  2416.         // • BotRight 4
  2417.         light = kMediumGray;
  2418.         SetRGBColor (dark, kRGB8BitGray8, kRGB8BitGray8, kRGB8BitGray8);
  2419.         this->BotRightCorner (insetArea, light, dark, hilite);
  2420.  
  2421.     }
  2422.  
  2423. } // T3DTextButtonAdorner::Draw8Bit
  2424.  
  2425. //----------------------------------------------------------------------------------------
  2426. // T3DTextButtonAdorner::Draw4Bit
  2427. //----------------------------------------------------------------------------------------
  2428. #pragma segment A3DControlRes
  2429.  
  2430. void T3DTextButtonAdorner::Draw4Bit (const CRect& rect, Boolean hilite)
  2431. {
  2432.     CRect             insetArea;
  2433.     CRect             controlArea;
  2434.     CRGBColor         color;
  2435.     CRGBColor         light;
  2436.     CRGBColor         dark;
  2437.  
  2438.     // • Make a copy of the rect passed in
  2439.     controlArea = rect;
  2440.  
  2441.     // • Save off the area passed in
  2442.     insetArea = rect;
  2443.  
  2444.     // • Draw the hilited button
  2445.     if (hilite)
  2446.     {
  2447.         // • Outside edge of left top shadow
  2448.         SetRGBColor (color, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3);
  2449.         SetIfColor (color);
  2450.         MoveTo (controlArea.left, controlArea.bottom - 3);
  2451.         LineTo (controlArea.left, controlArea.top + 2);
  2452.         MoveTo (controlArea.left + 2, controlArea.top);
  2453.         LineTo (controlArea.right - 3, controlArea.top);
  2454.  
  2455.         // • Outside edge of bottom right shadow
  2456.         SetRGBColor (color, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1);
  2457.         SetIfColor (color);
  2458.         MoveTo (controlArea.left + 2, controlArea.bottom - 1);
  2459.         LineTo (controlArea.right - 3, controlArea.bottom - 1);
  2460.         MoveTo (controlArea.right - 1, controlArea.bottom - 3);
  2461.         LineTo (controlArea.right - 1, controlArea.top + 2);
  2462.  
  2463.         // • Inset our rectangle as we move to the next level
  2464.         InsetRect (controlArea, 1, 1);
  2465.  
  2466.         // • Inside edge of left top shadow
  2467.         SetRGBColor (color, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3);
  2468.         SetIfColor (color);
  2469.         MoveTo (controlArea.left, controlArea.bottom - 2);
  2470.         LineTo (controlArea.left, controlArea.top + 1);
  2471.         MoveTo (controlArea.left + 1, controlArea.top);
  2472.         LineTo (controlArea.right - 2, controlArea.top);
  2473.  
  2474.         // • Inside edge of bottom right shadow
  2475.         SetRGBColor (color, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1);
  2476.         SetIfColor (color);
  2477.         MoveTo (controlArea.left + 1, controlArea.bottom - 1);
  2478.         LineTo (controlArea.right - 2, controlArea.bottom - 1);
  2479.         MoveTo (controlArea.right - 1, controlArea.bottom - 2);
  2480.         LineTo (controlArea.right - 1, controlArea.top + 1);
  2481.  
  2482.         // •• Now draw the corners
  2483.         // • TopLeft 1
  2484.         SetRGBColor (light, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3);
  2485.         SetRGBColor (dark, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3);
  2486.         this->TopLeftCorner (insetArea, light, dark, hilite);
  2487.  
  2488.         // • TopRight 2
  2489.         SetRGBColor (light, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3);
  2490.         SetRGBColor (dark, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3);
  2491.         this->TopRightCorner (insetArea, light, dark, hilite);
  2492.  
  2493.         // • BotLeft 3
  2494.         // • Colors same as previous corner
  2495.         this->BotLeftCorner (insetArea, light, dark, hilite);
  2496.  
  2497.         // • BotRight 4
  2498.         SetRGBColor (light, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1);
  2499.         SetRGBColor (dark, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1);
  2500.         this->BotRightCorner (insetArea, light, dark, hilite);
  2501.  
  2502.     }
  2503.     else // • Draw the unhilited button
  2504.     {
  2505.         // • Outside edge of bottom right shadow
  2506.         SetRGBColor (color, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3);
  2507.         SetIfColor (color);
  2508.         MoveTo (controlArea.left + 2, controlArea.bottom - 1);
  2509.         LineTo (controlArea.right - 3, controlArea.bottom - 1);
  2510.         MoveTo (controlArea.right - 1, controlArea.bottom - 3);
  2511.         LineTo (controlArea.right - 1, controlArea.top + 2);
  2512.  
  2513.         // • Inset our rectangle as we move to the next level
  2514.         InsetRect (controlArea, 1, 1);
  2515.  
  2516.         // • Light on edge of button - light source edge
  2517.         SetIfColor (gRGBWhite);
  2518.         MoveTo (controlArea.left, controlArea.bottom - 2);
  2519.         LineTo (controlArea.left, controlArea.top + 1);
  2520.         MoveTo (controlArea.left + 1, controlArea.top);
  2521.         LineTo (controlArea.right - 2, controlArea.top);
  2522.  
  2523.         // • Inside edge of bottom right shadow
  2524.         SetRGBColor (color, kRGB4BitGray2, kRGB4BitGray2, kRGB4BitGray2);
  2525.         SetIfColor (color);
  2526.         MoveTo (controlArea.left + 1, controlArea.bottom - 1);
  2527.         LineTo (controlArea.right - 2, controlArea.bottom - 1);
  2528.         MoveTo (controlArea.right - 1, controlArea.bottom - 2);
  2529.         LineTo (controlArea.right - 1, controlArea.top + 1);
  2530.  
  2531.         // •• Now draw the corners
  2532.         // • TopLeft 1
  2533.         this->TopLeftCorner (insetArea, gRGBWhite, gRGBWhite, hilite);
  2534.  
  2535.         // • TopRight 2
  2536.         SetRGBColor (light, kRGB4BitGray2, kRGB4BitGray2, kRGB4BitGray2);
  2537.         this->TopRightCorner (insetArea, light, light, hilite);
  2538.  
  2539.         // • BotLeft 3
  2540.         // • Colors same as previous corner
  2541.         this->BotLeftCorner (insetArea, light, light, hilite);
  2542.  
  2543.         // • BotRight 4
  2544.         SetRGBColor (light, kRGB4BitGray2, kRGB4BitGray2, kRGB4BitGray2);
  2545.         SetRGBColor (dark, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3);
  2546.         this->BotRightCorner (insetArea, light, dark, hilite);
  2547.  
  2548.     }
  2549.  
  2550.  
  2551. } // T3DTextButtonAdorner::Draw4Bit
  2552.  
  2553. //----------------------------------------------------------------------------------------
  2554. // T3DTextButtonAdorner::Draw1Bit
  2555. // This routine is actually not called
  2556. //----------------------------------------------------------------------------------------
  2557. #pragma segment A3DControlRes
  2558.  
  2559. void T3DTextButtonAdorner::Draw1Bit (    const CRect& /*rect */, Boolean /*hilite*/)
  2560. {
  2561. // We don't actually use this now
  2562.  
  2563. } // T3DTextButtonAdorner::Draw1Bit
  2564.  
  2565. //----------------------------------------------------------------------------------------
  2566. // •• BUTTON FRAME
  2567. //----------------------------------------------------------------------------------------
  2568. // T3DTextButtonAdorner::Frame
  2569. //----------------------------------------------------------------------------------------
  2570. #pragma segment A3DControlRes
  2571.  
  2572. void T3DTextButtonAdorner::Frame (const CRect& rect)
  2573. {
  2574.     // • Draw the frame around the button this never changes
  2575.     FrameRoundRect (rect, kOvalWidth, kOvalHeight);
  2576.  
  2577. } // T3DTextButtonAdorner::Frame
  2578.  
  2579. //----------------------------------------------------------------------------------------
  2580. // •• CORNER DRAWING
  2581. //----------------------------------------------------------------------------------------
  2582. // T3DTextButtonAdorner::TopLeftCorner
  2583. //----------------------------------------------------------------------------------------
  2584. #pragma segment A3DControlRes
  2585.  
  2586. void T3DTextButtonAdorner::TopLeftCorner (const CRect& rect,
  2587.                                             const CRGBColor light,
  2588.                                             const CRGBColor dark,
  2589.                                             Boolean hilite )
  2590. {
  2591.     if (hilite)
  2592.     {
  2593.         // • Set the outer corner pixel
  2594.         SetIfColor(dark);
  2595.         MoveTo(rect.left + 1, rect.top + 1);
  2596.         LineTo(rect.left + 1, rect.top + 1);
  2597.  
  2598.         // • Set the inner corner pixel
  2599.         SetIfColor(light);
  2600.         MoveTo(rect.left + 2, rect.top + 2);
  2601.         LineTo(rect.left + 2, rect.top + 2);
  2602.     }
  2603.     else
  2604.     {
  2605.         // • Set the outer corner pixel
  2606.         SetIfColor(light);
  2607.         MoveTo(rect.left + 1, rect.top + 1);
  2608.         LineTo(rect.left + 1, rect.top + 1);
  2609.  
  2610.         // • Set the inner corner pixel
  2611.         SetIfColor(dark);
  2612.         MoveTo(rect.left + 2, rect.top + 2);
  2613.         LineTo(rect.left + 2, rect.top + 2);
  2614.     }
  2615.  
  2616. } // T3DTextButtonAdorner::TopLeftCorner
  2617.  
  2618. //----------------------------------------------------------------------------------------
  2619. // T3DTextButtonAdorner::TopRightCorner
  2620. //----------------------------------------------------------------------------------------
  2621. #pragma segment A3DControlRes
  2622.  
  2623. void T3DTextButtonAdorner::TopRightCorner (    const CRect& rect,
  2624.                                             const CRGBColor light,
  2625.                                             const CRGBColor dark,
  2626.                                             Boolean hilite )
  2627. {
  2628.     if (hilite)
  2629.     {
  2630.         // • Set the outer corner pixel
  2631.         SetIfColor(dark);
  2632.         MoveTo(rect.right - 2, rect.top + 1);
  2633.         LineTo(rect.right - 2, rect.top + 1);
  2634.  
  2635.         // • Set the inner corner pixel
  2636.         SetIfColor(light);
  2637.         MoveTo(rect.right - 3, rect.top + 2);
  2638.         LineTo(rect.right - 3, rect.top + 2);
  2639.     }
  2640.     else
  2641.     {
  2642.         // • Set the outer corner pixel
  2643.         SetIfColor(light);
  2644.         MoveTo(rect.right - 2, rect.top + 1);
  2645.         LineTo(rect.right - 2, rect.top + 1);
  2646.  
  2647.         // • Set the inner corner pixel
  2648.         SetIfColor(dark);
  2649.         MoveTo(rect.right - 3, rect.top + 2);
  2650.         LineTo(rect.right - 3, rect.top + 2);
  2651.     }
  2652.  
  2653. } // T3DTextButtonAdorner::TopRightCorner
  2654.  
  2655. //----------------------------------------------------------------------------------------
  2656. // T3DTextButtonAdorner::BotLeftCorner
  2657. //----------------------------------------------------------------------------------------
  2658. #pragma segment A3DControlRes
  2659.  
  2660. void T3DTextButtonAdorner::BotLeftCorner (    const CRect& rect,
  2661.                                             const CRGBColor light,
  2662.                                             const CRGBColor dark,
  2663.                                             Boolean hilite )
  2664. {
  2665.     if (hilite)
  2666.     {
  2667.         // • Set the outer corner pixel
  2668.         SetIfColor(dark);
  2669.         MoveTo(rect.left + 1, rect.bottom - 2);
  2670.         LineTo(rect.left + 1, rect.bottom - 2);
  2671.  
  2672.         // • Set the inner corner pixel
  2673.         SetIfColor(light);
  2674.         MoveTo(rect.left + 2, rect.bottom - 3);
  2675.         LineTo(rect.left + 2, rect.bottom - 3);
  2676.     }
  2677.     else
  2678.     {
  2679.         // • Set the outer corner pixel
  2680.         SetIfColor(light);
  2681.         MoveTo(rect.left + 1, rect.bottom - 2);
  2682.         LineTo(rect.left + 1, rect.bottom - 2);
  2683.  
  2684.         // • Set the inner corner pixel
  2685.         SetIfColor(dark);
  2686.         MoveTo(rect.left + 2, rect.bottom - 3);
  2687.         LineTo(rect.left + 2, rect.bottom - 3);
  2688.     }
  2689. } // T3DTextButtonAdorner::BotLeftCorner
  2690.  
  2691. //----------------------------------------------------------------------------------------
  2692. // T3DTextButtonAdorner::BotRightCorner
  2693. //----------------------------------------------------------------------------------------
  2694. #pragma segment A3DControlRes
  2695.  
  2696. void T3DTextButtonAdorner::BotRightCorner (const CRect& rect,
  2697.                                             const CRGBColor light,
  2698.                                             const CRGBColor dark,
  2699.                                             Boolean hilite)
  2700. {
  2701.     if (hilite)
  2702.     {
  2703.         // • Set the outer corner pixel
  2704.         SetIfColor(light);
  2705.         MoveTo(rect.right - 2, rect.bottom - 2);
  2706.         LineTo(rect.right - 2, rect.bottom - 2);
  2707.  
  2708.         // • Set the inner corner pixel
  2709.         SetIfColor(dark);
  2710.         MoveTo(rect.right - 3, rect.bottom - 3);
  2711.         LineTo(rect.right - 3, rect.bottom - 3);
  2712.     }
  2713.     else
  2714.     {
  2715.         // • Set the outer corner pixel
  2716.         SetIfColor(dark);
  2717.         MoveTo(rect.right - 2, rect.bottom - 2);
  2718.         LineTo(rect.right - 2, rect.bottom - 2);
  2719.  
  2720.         // • Set the inner corner pixel
  2721.         SetIfColor(light);
  2722.         MoveTo(rect.right - 3, rect.bottom - 3);
  2723.         LineTo(rect.right - 3, rect.bottom - 3);
  2724.     }
  2725.  
  2726. } // T3DTextButtonAdorner::BotRightCorner
  2727.  
  2728. //----------------------------------------------------------------------------------------
  2729. // ••• 3DIconButton class and auxiliary adorner •••
  2730. //----------------------------------------------------------------------------------------
  2731.  
  2732. //----------------------------------------------------------------------------------------
  2733. // T3DIconAdorner
  2734. // This is an auxiliary adorner for T3DIconButtons
  2735. //----------------------------------------------------------------------------------------
  2736.  
  2737. //----------------------------------------------------------------------------------------
  2738. // T3DIconAdorner::I3DIconAdorner
  2739. //----------------------------------------------------------------------------------------
  2740. #pragma segment A3DControlOpen
  2741.  
  2742. #undef Inherited
  2743. #define Inherited TAdorner
  2744. DefineClass(T3DIconAdorner, TAdorner);
  2745.  
  2746. void T3DIconAdorner::I3DIconAdorner (    Boolean freeOnDeletion )
  2747. {
  2748.     // • Call our superclass to complete initialization
  2749.     this->IAdorner ( k3DIconAdorner,freeOnDeletion );
  2750.  
  2751. } // T3DIconAdorner::I3DIconAdorner
  2752.  
  2753. //----------------------------------------------------------------------------------------
  2754. // •• DRAWING
  2755. //----------------------------------------------------------------------------------------
  2756. // T3DIconAdorner::Draw
  2757. //----------------------------------------------------------------------------------------
  2758. //
  2759. // This overridden draw method handles the drawing of the buttons border and then
  2760. // branches to the appropriate appropriate method to draw the buttons contents, based
  2761. // on the bit depth of the device being drawn to.  Currently this method supports 1, 4,
  2762. // and 8 bit or more devices.
  2763.  
  2764. #pragma segment A3DControlRes
  2765.  
  2766. void T3DIconAdorner::Draw (     TView* itsView, const VRect& /*area*/ )
  2767. {
  2768.     VRect                theRect;
  2769.     CRect                qdArea;
  2770.     short                pixelSize;
  2771.  
  2772.     // • Instantiate a stack based object that saves our graphic state
  2773.     CGraphicsState aGraphicsState;
  2774.  
  2775.     // • Coerce the view to a control and then get its QD area
  2776.     TControl* theControl = (TControl*)itsView;
  2777.     theControl->ControlArea ( theRect );
  2778.     theControl->ViewToQDRect ( theRect, qdArea );
  2779.  
  2780.     // • Frame button with a black border that has a pixel missing in each corner
  2781.     // this is drawn outside the while loop because it is always in black & white
  2782.     if (((TControl *)itsView)->IsDimmed())
  2783.         SetIfColor(kMediumGray);
  2784.     else
  2785.         SetIfColor ( gRGBBlack );
  2786.     this->Frame ( qdArea );
  2787.  
  2788.     // • Inset the area in preparartion for the drawing of the buttons content
  2789.     InsetRect ( qdArea, 1, 1 );
  2790.  
  2791.     // • Instantiate the stack based object that handles the per device clipping
  2792.     // the area is passed in so that the object can do clipping from it
  2793.     if (((TControl *)itsView)->IsDimmed())
  2794.     {
  2795.         // Hack for non-CQD
  2796.         CDrawPerDevice device ( qdArea );
  2797.         while ( device.NextDevice ( pixelSize ) )
  2798.         {
  2799.             if ( pixelSize < 4 )
  2800.             {
  2801.                 // Redraw the frame because it didn't draw if we're in non-CQD
  2802.                 CRect tempArea = qdArea;
  2803.                 CPenNormal();
  2804.                 InsetRect(tempArea, -1, -1);
  2805.                 this->Frame ( tempArea );
  2806.             }
  2807.         }
  2808.     }
  2809.     else
  2810.     {
  2811.         CDrawPerDevice device ( qdArea );
  2812.  
  2813.         // • We will cycle through all of the devices, drawing will be handle based on
  2814.         // the pixel size for each device
  2815.         while ( device.NextDevice ( pixelSize ) )
  2816.         {
  2817.  
  2818.             // • Draw the button with full colors - there should really be two levels of
  2819.             // drawing here, one for 4 bit color and one for 8 bit.
  2820.             if ( pixelSize >= 8 )
  2821.             {
  2822.  
  2823.                 // • Draw the button assuming 8 bit or better color
  2824.                 this->Draw8Bit ( qdArea, theControl->fHilite );
  2825.  
  2826.             }
  2827.             else if ( pixelSize == 4 )    // • Draw with only 16 colors
  2828.             {
  2829.  
  2830.                 // • For now we will draw the 1 bit style for 4 bit, but this should be
  2831.                 // replaced with a 4 bit algorithm which will give you 3 shades of gray
  2832.                 this->Draw4Bit ( qdArea, theControl->fHilite );
  2833.  
  2834.             }
  2835.             else if ( pixelSize < 4 )    // • Draw with 4 colors or less (no grays)
  2836.             {
  2837.                 // • Draw the 1 bit style for anything under 4 bit
  2838.                 this->Draw1Bit ( qdArea, theControl->fHilite );
  2839.  
  2840.             }
  2841.         }
  2842.     }
  2843.  
  2844. } // T3DIconAdorner::Draw
  2845.  
  2846. //----------------------------------------------------------------------------------------
  2847. // •• PRIVATE DRAWING
  2848. //----------------------------------------------------------------------------------------
  2849. // T3DIconAdorner::Draw8Bit
  2850. //----------------------------------------------------------------------------------------
  2851. #pragma segment A3DControlRes
  2852.  
  2853. void T3DIconAdorner::Draw8Bit ( const CRect& rect, Boolean hilite )
  2854. {
  2855.     CRect             insetArea;
  2856.     CRect             controlArea;
  2857.     CRGBColor         color;
  2858.     CRGBColor         light;
  2859.     CRGBColor         dark;
  2860.  
  2861.     // • Make a copy of the rect passed in
  2862.     controlArea = rect;
  2863.  
  2864.     // • Save off the area passed in
  2865.     insetArea = rect;
  2866.  
  2867.     // • Draw the hilited button
  2868.     if ( hilite )
  2869.     {
  2870.         // • Outside edge of left top shadow
  2871.         SetRGBColor ( color, kRGB8BitGray9, kRGB8BitGray9, kRGB8BitGray9 );
  2872.         SetIfColor ( color );
  2873.         this->TopLeftSide ( controlArea );
  2874.  
  2875.         // • Outside edge of bottom right shadow
  2876.         SetRGBColor ( color, kRGB8BitGray3, kRGB8BitGray3, kRGB8BitGray3 );
  2877.         SetIfColor ( color );
  2878.         this->BotRightSide ( controlArea );
  2879.  
  2880.         // • Inset our rectangle as we move to the next level
  2881.         InsetRect ( controlArea, 1, 1 );
  2882.  
  2883.         // • Inside edge of left top shadow
  2884.         SetRGBColor ( color, kRGB8BitGray8, kRGB8BitGray8, kRGB8BitGray8 );
  2885.         SetIfColor ( color );
  2886.         this->TopLeftSide ( controlArea );
  2887.  
  2888.         // • Inside edge of bottom right shadow
  2889.         color = kMediumLightGray;
  2890.         SetIfColor ( color );
  2891.         this->BotRightSide ( controlArea );
  2892.  
  2893.         // •• Now draw the corners
  2894.         // • TopLeft 1
  2895.         SetRGBColor ( light, kRGB8BitGray9, kRGB8BitGray9, kRGB8BitGray9 );
  2896.         SetRGBColor ( dark, kRGB8BitGray10, kRGB8BitGray10, kRGB8BitGray10 );
  2897.         this->TopLeftCorner ( insetArea, light, dark );
  2898.  
  2899.         // • TopRight 2
  2900.         light = kMediumGray;
  2901.         SetRGBColor ( dark, kRGB8BitGray7, kRGB8BitGray7, kRGB8BitGray7 );
  2902.         this->TopRightCorner ( insetArea, light, dark );
  2903.  
  2904.         // • BotLeft 3
  2905.         // • Colors same as previous corner
  2906.         this->BotLeftCorner ( insetArea, light, dark );
  2907.  
  2908.         // • BotRight 4
  2909.         light = kLightGray2;
  2910.         SetRGBColor ( dark, kRGB8BitGray3, kRGB8BitGray3, kRGB8BitGray3 );
  2911.         this->BotRightCorner ( insetArea, light, dark, hilite );
  2912.  
  2913.         // • Setup fill color for buttons face - hilite
  2914.         color = kMediumGray;
  2915.  
  2916.     }
  2917.     else // • Draw the unhilited button
  2918.     {
  2919.         // • Outside edge of left top shadow
  2920.         color = kLightGray2;
  2921.         SetIfColor ( color );
  2922.         this->TopLeftSide ( controlArea );
  2923.  
  2924.         // • Outside edge of bottom right shadow
  2925.         SetRGBColor ( color, kRGB8BitGray7, kRGB8BitGray7, kRGB8BitGray7 );
  2926.         SetIfColor ( color );
  2927.         this->BotRightSide ( controlArea );
  2928.  
  2929.         // • Inset our rectangle as we move to the next level
  2930.         InsetRect ( controlArea, 1, 1 );
  2931.  
  2932.         // • Light on edge of button - light source edge
  2933.         SetIfColor ( gRGBWhite );
  2934.         this->TopLeftSide ( controlArea );
  2935.  
  2936.         // • Inside edge of bottom right shadow
  2937.         color = kMediumGray;
  2938.         SetIfColor ( color );
  2939.         this->BotRightSide ( controlArea );
  2940.  
  2941.         // •• Now draw the corners
  2942.         // • TopLeft 1
  2943.         this->TopLeftCorner ( insetArea, gRGBWhite, gRGBWhite );
  2944.  
  2945.         // • TopRight 2
  2946.         SetRGBColor ( light, kRGB8BitGray3, kRGB8BitGray3, kRGB8BitGray3 );
  2947.         this->TopRightCorner ( insetArea, light, light );
  2948.  
  2949.         // • BotLeft 3
  2950.         // • Colors same as previous corner
  2951.         this->BotLeftCorner ( insetArea, light, light );
  2952.  
  2953.         // • BotRight 4
  2954.         SetRGBColor ( light, kRGB8BitGray8, kRGB8BitGray8, kRGB8BitGray8 );
  2955.         SetRGBColor ( dark, kRGB8BitGray9, kRGB8BitGray9, kRGB8BitGray9 );
  2956.         this->BotRightCorner ( insetArea, light, dark, hilite );
  2957.  
  2958.         // • Setup fill color for button face
  2959.         color = kLightGray2;
  2960.  
  2961.     }
  2962.  
  2963.     // • Inset our rectangle so that we can fill the rest of the area
  2964.     InsetRect ( controlArea, 1, 1 );
  2965.  
  2966.     // • Now we will fill the rest of the button NOTE: color was setup at the
  2967.     // end of either the hilite or normal draw routines
  2968.     SetIfColor ( color );
  2969.     PaintRect ( controlArea );
  2970.  
  2971. } // T3DIconAdorner::Draw8Bit
  2972.  
  2973. //----------------------------------------------------------------------------------------
  2974. // T3DIconAdorner::Draw4Bit
  2975. //----------------------------------------------------------------------------------------
  2976. #pragma segment A3DControlRes
  2977.  
  2978. void T3DIconAdorner::Draw4Bit ( const CRect& rect, Boolean hilite )
  2979. {
  2980.     CRect             insetArea;
  2981.     CRect             controlArea;
  2982.     CRGBColor         color;
  2983.     CRGBColor         light;
  2984.     CRGBColor         dark;
  2985.  
  2986.     // • Make a copy of the rect passed in
  2987.     controlArea = rect;
  2988.  
  2989.     // • Save off the area passed in
  2990.     insetArea = rect;
  2991.  
  2992.     // • Draw the hilited button
  2993.     if ( hilite )
  2994.     {
  2995.         // • Outside edge of left top shadow
  2996.         SetRGBColor ( color, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3 );
  2997.         SetIfColor ( color );
  2998.         this->TopLeftSide ( controlArea );
  2999.  
  3000.         // • Outside edge of bottom right shadow
  3001.         SetRGBColor ( color, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1 );
  3002.         SetIfColor ( color );
  3003.         this->BotRightSide ( controlArea );
  3004.  
  3005.         // • Inset our rectangle as we move to the next level
  3006.         InsetRect ( controlArea, 1, 1 );
  3007.  
  3008.         // • Inside edge of left top shadow
  3009.         SetRGBColor ( color, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3 );
  3010.         SetIfColor ( color );
  3011.         this->TopLeftSide ( controlArea );
  3012.  
  3013.         // • Inside edge of bottom right shadow
  3014.         SetRGBColor ( color, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1 );
  3015.         SetIfColor ( color );
  3016.         this->BotRightSide ( controlArea );
  3017.  
  3018.         // •• Now draw the corners
  3019.         // • TopLeft 1
  3020.         SetRGBColor ( light, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3 );
  3021.         this->TopLeftCorner ( insetArea, light, light );
  3022.  
  3023.         // • TopRight 2
  3024.         SetRGBColor ( light, kRGB4BitGray2, kRGB4BitGray2, kRGB4BitGray2 );
  3025.         this->TopRightCorner ( insetArea, light, light );
  3026.  
  3027.         // • BotLeft 3
  3028.         SetRGBColor ( light, kRGB4BitGray2, kRGB4BitGray2, kRGB4BitGray2 );
  3029.         this->BotLeftCorner ( insetArea, light, light );
  3030.  
  3031.         // • BotRight 4
  3032.         SetRGBColor ( light, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1 );
  3033.         this->BotRightCorner ( insetArea, light, light, hilite );
  3034.  
  3035.         // • Setup fill color for button face - hilite
  3036.         SetRGBColor ( color, kRGB4BitGray2, kRGB4BitGray2, kRGB4BitGray2 );
  3037.  
  3038.     }
  3039.     else // • Draw the unhilited button
  3040.     {
  3041.         // • Outside edge of left top shadow
  3042.         SetRGBColor ( color, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1 );
  3043.         SetIfColor ( color );
  3044.         this->TopLeftSide ( controlArea );
  3045.  
  3046.         // • Outside edge of bottom right shadow
  3047.         SetRGBColor ( color, kRGB4BitGray2, kRGB4BitGray2, kRGB4BitGray2 );
  3048.         SetIfColor ( color );
  3049.         this->BotRightSide ( controlArea );
  3050.  
  3051.         // • Inset our rectangle as we move to the next level
  3052.         InsetRect ( controlArea, 1, 1 );
  3053.  
  3054.         // • Light on edge of button - light source edge
  3055.         SetIfColor ( gRGBWhite );
  3056.         this->TopLeftSide ( controlArea );
  3057.  
  3058.         // • Inside edge of bottom right shadow
  3059.         SetRGBColor ( color, kRGB4BitGray2, kRGB4BitGray2, kRGB4BitGray2 );
  3060.         SetIfColor ( color );
  3061.         this->BotRightSide ( controlArea );
  3062.  
  3063.         // •• Now draw the corners
  3064.         // • TopLeft 1
  3065.         this->TopLeftCorner ( insetArea, gRGBWhite, gRGBWhite );
  3066.  
  3067.         // • TopRight 2
  3068.         SetRGBColor ( light, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1 );
  3069.         this->TopRightCorner ( insetArea, light, light );
  3070.  
  3071.         // • BotLeft 3
  3072.         // • Colors same as previous corner
  3073.         this->BotLeftCorner ( insetArea, light, light );
  3074.  
  3075.         // • BotRight 4
  3076.         SetRGBColor ( light, kRGB4BitGray3, kRGB4BitGray3, kRGB4BitGray3 );
  3077.         this->BotRightCorner ( insetArea, light, light, hilite );
  3078.  
  3079.         // • Setup fill color for button face
  3080.         SetRGBColor ( color, kRGB4BitGray1, kRGB4BitGray1, kRGB4BitGray1 );
  3081.  
  3082.     }
  3083.  
  3084.     // • Inset our rectangle so that we can fill the rest of the area
  3085.     InsetRect ( controlArea, 1, 1 );
  3086.  
  3087.     // • Now we will fill the rest of the button NOTE: color was setup at the
  3088.     // end of either the hilite or normal draw routines
  3089.     SetIfColor ( color );
  3090.     PaintRect ( controlArea );
  3091.  
  3092. } // T3DIconAdorner::Draw4Bit
  3093.  
  3094. //----------------------------------------------------------------------------------------
  3095. // T3DIconAdorner::Draw1Bit
  3096. //----------------------------------------------------------------------------------------
  3097. #pragma segment A3DControlRes
  3098.  
  3099. void T3DIconAdorner::Draw1Bit ( const CRect& rect, Boolean hilite )
  3100. {
  3101.     CRect insetArea;
  3102.     CRect controlArea;
  3103.  
  3104.     CPenNormal();
  3105.  
  3106.     // • Make a copy of the rect passed in
  3107.     controlArea = rect;
  3108.  
  3109.     // • Save off the area passed in
  3110.     insetArea = controlArea;
  3111.  
  3112.     // • First we paint the inside white
  3113.     PenPat(&qd.white);
  3114.     ForeColor ( whiteColor );
  3115.     PaintRect ( controlArea );
  3116.  
  3117.     // • Outside edge of bottom right shadow
  3118.     PenPat ( &qd.gray );
  3119.     ForeColor ( blackColor );
  3120.     this->BotRightSide ( controlArea );
  3121.  
  3122.     // • Inset the rectangle again for the next level
  3123.     InsetRect ( controlArea, 1, 1 );
  3124.  
  3125.     // • Inside edge of bottom right shadow
  3126.     this->BotRightSide ( controlArea );
  3127.  
  3128.     // • We are hiliting so we need to invert the whole thing
  3129.     if  ( hilite )
  3130.         InvertRect ( insetArea );
  3131.  
  3132. } // T3DIconAdorner::Draw1Bit
  3133.  
  3134. //----------------------------------------------------------------------------------------
  3135. // •• BUTTON FRAME
  3136. //----------------------------------------------------------------------------------------
  3137. // T3DIconAdorner::Frame
  3138. //----------------------------------------------------------------------------------------
  3139. #pragma segment A3DControlRes
  3140.  
  3141. void T3DIconAdorner::Frame ( const CRect& rect )
  3142. {
  3143.     // • Draw the frame around the button this never changes
  3144.     MoveTo ( rect.left, rect.bottom - 2 );
  3145.     LineTo ( rect.left, rect.top + 1 );
  3146.     MoveTo ( rect.left + 1, rect.top );
  3147.     LineTo ( rect.right - 2, rect.top );
  3148.     MoveTo ( rect.left + 1, rect.bottom - 1 );
  3149.     LineTo ( rect.right - 2, rect.bottom - 1 );
  3150.     MoveTo ( rect.right - 1, rect.bottom - 2 );
  3151.     LineTo ( rect.right - 1, rect.top + 1 );
  3152.  
  3153. } // T3DIconAdorner::Frame
  3154.  
  3155. //----------------------------------------------------------------------------------------
  3156. // •• EDGE DRAWING
  3157. //----------------------------------------------------------------------------------------
  3158. // T3DIconAdorner::TopLeftSide
  3159. //----------------------------------------------------------------------------------------
  3160. #pragma segment A3DControlRes
  3161.  
  3162. void T3DIconAdorner::TopLeftSide ( const CRect& rect )
  3163. {
  3164.     MoveTo ( rect.left,rect.bottom-2 );
  3165.     LineTo ( rect.left,rect.top );
  3166.     LineTo ( rect.right-2,rect.top );
  3167.  
  3168. } // T3DIconAdorner::TopLeftSide
  3169.  
  3170. //----------------------------------------------------------------------------------------
  3171. // T3DIconAdorner::BotRightSide
  3172. //----------------------------------------------------------------------------------------
  3173. #pragma segment A3DControlRes
  3174.  
  3175. void T3DIconAdorner::BotRightSide ( const CRect& rect )
  3176. {
  3177.     MoveTo ( rect.left,rect.bottom-1 );
  3178.     LineTo ( rect.right-1,rect.bottom-1 );
  3179.     LineTo ( rect.right-1,rect.top );
  3180.  
  3181. } // T3DIconAdorner::BotRightSide
  3182.  
  3183. //----------------------------------------------------------------------------------------
  3184. // •• CORNER DRAWING
  3185. //----------------------------------------------------------------------------------------
  3186. // T3DIconAdorner::TopLeftCorner
  3187. //----------------------------------------------------------------------------------------
  3188. #pragma segment A3DControlRes
  3189.  
  3190. void T3DIconAdorner::TopLeftCorner (     const CRect& rect,
  3191.                                         const CRGBColor light,
  3192.                                         const CRGBColor dark  )
  3193. {
  3194.     // • Set the outer corner pixel
  3195.     SetIfColor(dark);
  3196.     MoveTo(rect.left, rect.top);
  3197.     LineTo(rect.left, rect.top);
  3198.  
  3199.     // • Set the inner corner pixel
  3200.     SetIfColor(light);
  3201.     MoveTo(rect.left + 1, rect.top + 1);
  3202.     LineTo(rect.left + 1, rect.top + 1);
  3203.  
  3204. } // T3DIconAdorner::TopLeftCorner
  3205.  
  3206. //----------------------------------------------------------------------------------------
  3207. // T3DIconAdorner::TopRightCorner
  3208. //----------------------------------------------------------------------------------------
  3209. #pragma segment A3DControlRes
  3210.  
  3211. void T3DIconAdorner::TopRightCorner (    const CRect& rect,
  3212.                                         const CRGBColor light,
  3213.                                         const CRGBColor dark  )
  3214. {
  3215.     // • Set the outer corner pixel
  3216.     SetIfColor(light);
  3217.     MoveTo(rect.right - 1, rect.top);
  3218.     LineTo(rect.right - 1, rect.top);
  3219.  
  3220.     // • Set the inner corner pixel
  3221.     SetIfColor(dark);
  3222.     MoveTo(rect.right - 2, rect.top + 1);
  3223.     LineTo(rect.right - 2, rect.top + 1);
  3224.  
  3225. } // T3DIconAdorner::TopRightCorner
  3226.  
  3227. //----------------------------------------------------------------------------------------
  3228. // T3DIconAdorner::BotLeftCorner
  3229. //----------------------------------------------------------------------------------------
  3230. #pragma segment A3DControlRes
  3231.  
  3232. void T3DIconAdorner::BotLeftCorner (     const CRect& rect,
  3233.                                         const CRGBColor light,
  3234.                                         const CRGBColor dark  )
  3235. {
  3236.     // • Set the outer corner pixel
  3237.     SetIfColor(light);
  3238.     MoveTo(rect.left, rect.bottom - 1);
  3239.     LineTo(rect.left, rect.bottom - 1);
  3240.  
  3241.     // • Set the inner corner pixel
  3242.     SetIfColor(dark);
  3243.     MoveTo(rect.left + 1, rect.bottom - 2);
  3244.     LineTo(rect.left + 1, rect.bottom - 2);
  3245.  
  3246. } // T3DIconAdorner::BotLeftCorner
  3247.  
  3248. //----------------------------------------------------------------------------------------
  3249. // T3DIconAdorner::BotRightCorner
  3250. //----------------------------------------------------------------------------------------
  3251. #pragma segment A3DControlRes
  3252.  
  3253. void T3DIconAdorner::BotRightCorner (    const CRect& rect,
  3254.                                         const CRGBColor light,
  3255.                                         const CRGBColor dark,
  3256.                                         Boolean hilite )
  3257. {
  3258.     if ( hilite )
  3259.     {
  3260.         // • Set the outer corner pixel
  3261.         SetIfColor(light);
  3262.         MoveTo(rect.right - 1, rect.bottom - 1);
  3263.         LineTo(rect.right - 1, rect.bottom - 1);
  3264.  
  3265.         // • Set the inner corner pixel
  3266.         SetIfColor(dark);
  3267.         MoveTo(rect.right - 2, rect.bottom - 2);
  3268.         LineTo(rect.right - 2, rect.bottom - 2);
  3269.     }
  3270.     else
  3271.     {
  3272.         // • Set the outer corner pixel
  3273.         SetIfColor(dark);
  3274.         MoveTo(rect.right - 1, rect.bottom - 1);
  3275.         LineTo(rect.right - 1, rect.bottom - 1);
  3276.  
  3277.         // • Set the inner corner pixel
  3278.         SetIfColor(light);
  3279.         MoveTo(rect.right - 2, rect.bottom - 2);
  3280.         LineTo(rect.right - 2, rect.bottom - 2);
  3281.     }
  3282.  
  3283. } // T3DIconAdorner::BotRightCorner
  3284.  
  3285. //----------------------------------------------------------------------------------------
  3286. // CLASS:    TIconSuite
  3287. // The T3DIconButton class is based from this one.  However, you can use this
  3288. // class alone if you wish.  It will draw an icon suite and allow you to
  3289. // apply standard masks to respond to events
  3290. //----------------------------------------------------------------------------------------
  3291.  
  3292. //----------------------------------------------------------------------------------------
  3293. // •• INITIALIZATION & DISPOSAL
  3294. //----------------------------------------------------------------------------------------
  3295. // TIconSuite::Initialize
  3296. //----------------------------------------------------------------------------------------
  3297. #pragma segment    A3DControlOpen
  3298.  
  3299. #undef Inherited
  3300. #define Inherited TControl
  3301. DefineClass(TIconSuite, TControl);
  3302.  
  3303. void TIconSuite::Initialize ()    // OVERRIDE
  3304. {
  3305.     fIconSuiteRsrcID = kNoResource;
  3306.     fAlignment = atNone;
  3307.     fDataHandle = NULL;
  3308.     fSelectorValue  = svAllAvailableData;
  3309.  
  3310. }    // TIconSuite::Initialize
  3311.  
  3312. //----------------------------------------------------------------------------------------
  3313. // TIconSuite::IIconSuite
  3314. //----------------------------------------------------------------------------------------
  3315. #pragma segment    A3DControlOpen
  3316.  
  3317. void TIconSuite::IIconSuite (    TView* itsSuperView,
  3318.                                 const VPoint& itsLocation,
  3319.                                 const VPoint& itsSize,
  3320.                                 SizeDeterminer itsHSizeDet,
  3321.                                 SizeDeterminer itsVSizeDet,
  3322.                                 ResNumber itsRsrcID,
  3323.                                 IconAlignmentType    alignment,
  3324.                                 IconSelectorValue selectorValue)
  3325. {
  3326.     FailInfo fi;
  3327.  
  3328.     this->IControl ( itsSuperView, itsLocation, itsSize, itsHSizeDet, itsVSizeDet );
  3329.  
  3330.     // • Setup our fields
  3331.     fAlignment = alignment;
  3332.     fEventNumber = mIconSuiteHit;                // We will use the mIconSuiteHit constant
  3333.  
  3334.     // • Installs the icon suite
  3335.     this->SetIconSuiteRsrcID ( itsRsrcID,selectorValue,kDontRedraw );
  3336.  
  3337.     // • Default is to enable hit testing
  3338.     this->SetEnable ( true );
  3339.  
  3340. }    // TIconSuite::IIconSuite
  3341.  
  3342. //----------------------------------------------------------------------------------------
  3343. // TIconSuite::DoPostCreate
  3344. //----------------------------------------------------------------------------------------
  3345. #pragma segment    A3DControlOpen
  3346.  
  3347. void TIconSuite::DoPostCreate(TDocument *itsDocument)
  3348. {
  3349.     Inherited::DoPostCreate(itsDocument);
  3350.  
  3351.     fEventNumber = mIconSuiteHit;                // We will use the mIconSuiteHit constant
  3352.     fAlignment = atNone;
  3353.  
  3354.     // • Installs the icon suite - use the fUserArea field of the View resource
  3355.     // as the icon suite
  3356.     this->SetIconSuiteRsrcID((short) fUserArea,svAllAvailableData,kDontRedraw);
  3357.  
  3358.     // • Default is to enable hit testing
  3359.     this->SetEnable ( true );
  3360. }
  3361.  
  3362. //----------------------------------------------------------------------------------------
  3363. // TIconSuite::Clone
  3364. //----------------------------------------------------------------------------------------
  3365. #pragma segment A3DControlNonRes
  3366.  
  3367. TObject* TIconSuite::Clone ()    // OVERRIDE
  3368. {
  3369.     TIconSuite* aClonedIconSuite;
  3370.     Handle itsRsrcHandle;
  3371.  
  3372.     // • First call Inherited clone and coerce the result to our type
  3373.     aClonedIconSuite = ( TIconSuite* )( Inherited::Clone ());
  3374.  
  3375.     // • Setup the cloned icon suite's fields
  3376.     aClonedIconSuite->fDataHandle = NULL;
  3377.     aClonedIconSuite->fAlignment = fAlignment;
  3378.  
  3379.     // • Now get a new copy of the resource handle and place it in the data field
  3380.     if ( fDataHandle )
  3381.     {
  3382.         // • Make the resource non-purgeable, so the Toolbox doesn't die
  3383.         GetIconSuite ( &itsRsrcHandle, fIconSuiteRsrcID, fSelectorValue );
  3384.  
  3385.         aClonedIconSuite->fDataHandle = itsRsrcHandle;
  3386.  
  3387.         // • Check to see if it is a NIL resource
  3388.         FailNILResource ( aClonedIconSuite->fDataHandle );
  3389.     }
  3390.  
  3391.     // • Return the cloned icon suite
  3392.     return aClonedIconSuite;
  3393.  
  3394. }    // TIconSuite::Clone
  3395.  
  3396. //----------------------------------------------------------------------------------------
  3397. // TIconSuite::Free
  3398. //----------------------------------------------------------------------------------------
  3399. #pragma segment A3DControlClose
  3400.  
  3401. void TIconSuite::Free ()    // OVERRIDE
  3402. {
  3403.     // • Get rid of the icon suite
  3404.     this->ReleaseIconSuite ();
  3405.  
  3406.     Inherited::Free ();
  3407.  
  3408. }    // TIconSuite::Free
  3409.  
  3410. //----------------------------------------------------------------------------------------
  3411. // TIconSuite::ReleaseIconSuite
  3412. //----------------------------------------------------------------------------------------
  3413. #pragma segment A3DControlNonRes
  3414.  
  3415. void TIconSuite::ReleaseIconSuite ()
  3416. {
  3417.     // • Set the rsrc ID field to nothing
  3418.     fIconSuiteRsrcID = kNoResource;
  3419.  
  3420.     // • If there is a data handle then dispose of the icon suite
  3421.     if ( fDataHandle )
  3422.     {
  3423.         OSErr    anError;
  3424.  
  3425.         anError = DisposeIconSuite ( fDataHandle, true );
  3426.         fDataHandle = NULL;
  3427.     }
  3428.  
  3429. }    // TIconSuite::ReleaseIconSuite
  3430.  
  3431. //----------------------------------------------------------------------------------------
  3432. // •• ACCESSORS
  3433. //----------------------------------------------------------------------------------------
  3434. // TIconSuite::GetIconRect
  3435. //----------------------------------------------------------------------------------------
  3436. #pragma segment A3DControlRes
  3437.  
  3438. void TIconSuite::GetIconRect ( VRect& theRect )
  3439. {
  3440.     this->ControlArea ( theRect );
  3441.  
  3442. }    // <- GetIconRect
  3443.  
  3444. //----------------------------------------------------------------------------------------
  3445. // TIconSuite::SetIconSuite
  3446. //----------------------------------------------------------------------------------------
  3447. #pragma segment A3DControlNonRes
  3448.  
  3449. void TIconSuite::SetIconSuite ( Handle theSuite, Boolean redraw )
  3450. {
  3451.     ResNumber     theID;
  3452.     ResType     theType;
  3453.     CStr255     name;
  3454.  
  3455.     // • Release the existing icon suite and set the data field to
  3456.     // the new icon suite
  3457.     this->ReleaseIconSuite();
  3458.     fDataHandle = theSuite;
  3459.  
  3460.     // • Get the rsrc ID from the icon suite's handle
  3461.     GetResInfo ( theSuite, &theID, &theType, name) ;
  3462.     if ( ResError() == noErr )
  3463.         fIconSuiteRsrcID = theID;
  3464.  
  3465.     // • Get everything redrawn so that the new icon can be displayed, if needed
  3466.     if ( redraw )
  3467.         this->ForceRedraw ();
  3468.  
  3469. }    // TIconSuite::SetIconSuite
  3470.  
  3471. //----------------------------------------------------------------------------------------
  3472. // TIconSuite::SetIconSuiteRsrcID
  3473. //----------------------------------------------------------------------------------------
  3474. #pragma segment A3DControlNonRes
  3475.  
  3476. void TIconSuite::SetIconSuiteRsrcID ( short itsRsrcID, IconSelectorValue selectorValue, Boolean redraw )
  3477. {
  3478.     FailInfo     fi;
  3479.     Handle         itsRsrcHandle;
  3480.  
  3481.     if ( itsRsrcID != kNoResource )
  3482.     {
  3483.         Try(fi)
  3484.         {
  3485.             // • Make the resource non-purgeable, so the Toolbox doesn't die
  3486.             GetIconSuite ( &itsRsrcHandle, itsRsrcID, fSelectorValue );
  3487.  
  3488.             // • Check to see if it is a NIL resource
  3489.             FailNILResource ( itsRsrcHandle );
  3490.  
  3491.             // • Release the existing icon suite
  3492.             this->ReleaseIconSuite();
  3493.  
  3494.             // • Place the resource handle in our data field
  3495.             fDataHandle = itsRsrcHandle;
  3496.             fIconSuiteRsrcID = itsRsrcID;
  3497.             fSelectorValue = selectorValue;
  3498.  
  3499.             // • Hey! everything worked fine, we're out of here!!
  3500.             fi.Success ();
  3501.         }
  3502.         else    // Recover
  3503.         {
  3504.             fi.ReSignal ();
  3505.         }
  3506.  
  3507.         // • Get everything redrawn so that the new icon can be displayed, if needed
  3508.         if ( redraw )
  3509.             this->ForceRedraw ();
  3510.  
  3511.     }
  3512.  
  3513. }    // TIconSuite::SetIconSuiteRsrcID
  3514.  
  3515. //----------------------------------------------------------------------------------------
  3516. // TIconSuite::SetAlignment
  3517. //----------------------------------------------------------------------------------------
  3518. #pragma segment A3DControlNonRes
  3519.  
  3520. void TIconSuite::SetAlignment ( IconAlignmentType newAlignment, Boolean redraw )
  3521. {
  3522.     // • Setup the field to the new alignment value
  3523.     fAlignment = newAlignment;
  3524.  
  3525.     // • Get everything redrawn so that the new icon can be displayed, if needed
  3526.     if ( redraw )
  3527.         this->ForceRedraw ();
  3528.  
  3529. }    // TIconSuite::SetAlignment
  3530.  
  3531. //----------------------------------------------------------------------------------------
  3532. // •• DRAWING
  3533. //----------------------------------------------------------------------------------------
  3534. // TIconSuite::Draw
  3535. //----------------------------------------------------------------------------------------
  3536. #pragma segment A3DControlRes
  3537.  
  3538. void TIconSuite::Draw ( const VRect& area )    // OVERRIDE
  3539. {
  3540.     // • Get the icon plotted with the "ttNone" transorm applied
  3541.     // this transform shows the icon in its normal state
  3542.     this->DoPlotIconSuite ( ttNone );
  3543.  
  3544.     Inherited::Draw ( area );
  3545.  
  3546. }    // <- Draw
  3547.  
  3548. //----------------------------------------------------------------------------------------
  3549. // TIconSuite::DoPlotIconSuite    PRIVATE
  3550. //----------------------------------------------------------------------------------------
  3551. #pragma segment A3DControlRes
  3552.  
  3553. void TIconSuite::DoPlotIconSuite ( IconTransformType transform )        // OVERRIDE
  3554. {
  3555.     SignedByte oldState;
  3556.     VRect theRect;
  3557.     CRect theQDRect;
  3558.  
  3559.     // • We will only do something if we have a datahandle
  3560.     if ( fDataHandle )
  3561.     {
  3562.         // • If the data handle we have is a resource then make sure its loaded
  3563.         if ( IsAResource ( fDataHandle ))
  3564.             LoadResource ( fDataHandle );
  3565.  
  3566.         if ( *fDataHandle )                // If there's room for the icon…
  3567.         {
  3568.             PenNormal();                        // NECESSARY?
  3569.  
  3570.             // • Get a Quickdraw rectangle of the control's extent
  3571.             this->GetIconRect ( theRect );
  3572.             this->ViewToQDRect ( theRect, theQDRect );
  3573.  
  3574.             // • Save off the state of the data handle
  3575.             oldState = HGetState ( fDataHandle );
  3576.             HNoPurge ( fDataHandle );
  3577.             HLock ( fDataHandle );
  3578.  
  3579.             // • Get the icon plotted using the transform passed in as
  3580.             // well as the current alignment
  3581.             PlotIconSuite ( theQDRect, fAlignment, transform, fDataHandle);
  3582.  
  3583.             // • Restore the dtata handle's state
  3584.             HSetState ( fDataHandle, oldState );
  3585.         }
  3586.     }
  3587.  
  3588. }    // TIconSuite::DoPlotIconSuite
  3589.  
  3590. //----------------------------------------------------------------------------------------
  3591. // •• STATE
  3592. //----------------------------------------------------------------------------------------
  3593. // TIconSuite::Dim
  3594. //----------------------------------------------------------------------------------------
  3595. #pragma segment A3DControlRes
  3596.  
  3597. void TIconSuite::Dim ()        // OVERRIDE
  3598. {
  3599.     // • Plot the icon disabled if we are dimmed
  3600.     this->DoPlotIconSuite ( ttDisabled );
  3601.  
  3602. }    // TIconSuite::Dim
  3603.  
  3604. //----------------------------------------------------------------------------------------
  3605. // TIconSuite::Hilite
  3606. //----------------------------------------------------------------------------------------
  3607. #pragma segment A3DControlRes
  3608.  
  3609. void TIconSuite::Hilite ()    // OVERRIDE
  3610. {
  3611.  
  3612.     // • If the icon is hilited then plot it "selected" otherwise plot is as
  3613.     // normal in its unselected state
  3614.     if ( fHilite )
  3615.         this->DoPlotIconSuite ( ttSelected );
  3616.     else
  3617.         this->DoPlotIconSuite ( ttNone );
  3618.  
  3619. }    // TIconSuite::Hilite
  3620.  
  3621. //----------------------------------------------------------------------------------------
  3622. // CLASS:    T3DIconButton
  3623. //----------------------------------------------------------------------------------------
  3624.  
  3625. const    short    kDefaultSize    = 32;
  3626. //----------------------------------------------------------------------------------------
  3627. // T3DIconButton::Initialize
  3628. //----------------------------------------------------------------------------------------
  3629. #pragma segment A3DControlOpen
  3630.  
  3631. #undef Inherited
  3632. #define Inherited TIconSuite
  3633. DefineClass(T3DIconButton, TIconSuite);
  3634.  
  3635. void T3DIconButton::Initialize ()                // Override
  3636. {
  3637.     f3DIconAdorner = NULL;
  3638.     fIconSize = kDefaultSize;        // Use 32x32 icons by default
  3639.     fMode = kButtonMode;            // Use button mode by default
  3640.     fState = false;
  3641.  
  3642. } // T3DIconButton::Initialize
  3643.  
  3644. //----------------------------------------------------------------------------------------
  3645. // T3DIconButton::I3DButton
  3646. //----------------------------------------------------------------------------------------
  3647. #pragma segment A3DControlOpen
  3648.  
  3649. void T3DIconButton::I3DIconButton (    TView* itsSuperView,
  3650.                                     const VPoint& itsLocation,
  3651.                                     const VPoint& itsSize,
  3652.                                     SizeDeterminer itsHSizeDet,
  3653.                                     SizeDeterminer itsVSizeDet,
  3654.                                     short iconSize,
  3655.                                     ResNumber itsRsrcID,
  3656.                                     ButtonMode mode,
  3657.                                     Boolean state )
  3658. {
  3659.     IconSelectorValue selectorValue;
  3660.  
  3661.     switch ( iconSize )
  3662.     {
  3663.     case 12:
  3664.         selectorValue = svAllMiniData;
  3665.         break;
  3666.     case 16:
  3667.         selectorValue = svAllSmallData;
  3668.         break;
  3669.     case 32:
  3670.         selectorValue = svAllLargeData;
  3671.         break;
  3672.     }
  3673.  
  3674.     // • Get our superclass setup
  3675.     this->IIconSuite ( itsSuperView, itsLocation, itsSize,
  3676.                         itsHSizeDet, itsVSizeDet,
  3677.                         itsRsrcID, atAbsoluteCenter, selectorValue );
  3678.  
  3679.     fIconSize  = iconSize;
  3680.     this->SetMode ( mode );
  3681.     fState = state;
  3682.     fEventNumber = mIconButtonHit;
  3683.  
  3684.     // • Get the correct hiliteState setup
  3685.     if ( fState )
  3686.         this->HiliteState ( fState, kRedraw );
  3687.  
  3688.     // • If we are being built procedurally then build the adorner
  3689.     if ( f3DIconAdorner == NULL )
  3690.         this->CreateButtonAdorner ();
  3691.  
  3692. } // T3DIconButton::I3DButton
  3693.  
  3694. //----------------------------------------------------------------------------------------
  3695. // T3DIconButton::DoPostCreate
  3696. //----------------------------------------------------------------------------------------
  3697. #pragma segment A3DControlOpen
  3698.  
  3699. void T3DIconButton::DoPostCreate ( TDocument *itsDocument ) // Override
  3700. {
  3701.  
  3702.     Inherited::DoPostCreate ( itsDocument );
  3703.  
  3704.     fEventNumber = mIconButtonHit;
  3705.  
  3706.     if ( f3DIconAdorner == NULL )
  3707.         this->CreateButtonAdorner ();
  3708.  
  3709. } // T3DIconButton::DoPostCreate
  3710.  
  3711. //----------------------------------------------------------------------------------------
  3712. // T3DIconButton::CreateButtonAdorner
  3713. //----------------------------------------------------------------------------------------
  3714. #pragma segment A3DControlOpen
  3715.  
  3716. void T3DIconButton::CreateButtonAdorner ()
  3717. {
  3718.  
  3719.     // • Add the 3D Button Adorner
  3720.     T3DIconAdorner* adorner = new T3DIconAdorner;
  3721.     adorner->I3DIconAdorner ( kFreeOnDeletion );
  3722.     f3DIconAdorner = adorner;
  3723.     this->AddAdorner ( adorner, kAdornFirst, kDontInvalidate );
  3724.  
  3725. } // T3DIconButton::CreateButtonAdorner
  3726.  
  3727. //----------------------------------------------------------------------------------------
  3728. // T3DIconButton::GetIconRect
  3729. //----------------------------------------------------------------------------------------
  3730. #pragma segment A3DControlRes
  3731.  
  3732. void T3DIconButton::GetIconRect ( VRect& theRect )
  3733. {
  3734.     this->ControlArea ( theRect );
  3735.  
  3736.     VCoordinate iconSize = this->GetIconSize ( theRect.GetSize () );
  3737.  
  3738.     // Center the icon
  3739.     theRect.top += ( theRect.bottom - theRect.top - iconSize ) / 2;
  3740.     theRect.bottom = theRect.top + iconSize;
  3741.     theRect.left += ( theRect.right - theRect.left - iconSize ) / 2;
  3742.     theRect.right = theRect.left + iconSize;
  3743.  
  3744. }    // T3DIconButton::GetIconRect
  3745.  
  3746. //----------------------------------------------------------------------------------------
  3747. // T3DIconButton::GetIconSize
  3748. //----------------------------------------------------------------------------------------
  3749. #pragma segment A3DControlNonRes
  3750.  
  3751. short T3DIconButton::GetIconSize ( const VPoint& /*viewSize*/ )
  3752. {
  3753.     return fIconSize;
  3754.  
  3755. } // T3DIconButton::GetIconSize
  3756.  
  3757. //----------------------------------------------------------------------------------------
  3758. // T3DIconButton::Hilite
  3759. //----------------------------------------------------------------------------------------
  3760. #pragma segment A3DControlRes
  3761.  
  3762. void T3DIconButton::Hilite ()        // Override
  3763. {
  3764.     VRect    area;
  3765.     this->GetExtent ( area) ;
  3766.     f3DIconAdorner->Draw ( this, area );
  3767.  
  3768.     Inherited::Hilite ();
  3769.  
  3770. } // T3DIconButton::Hilite
  3771.  
  3772. //----------------------------------------------------------------------------------------
  3773. // T3DIconButton::Dim
  3774. //----------------------------------------------------------------------------------------
  3775. #pragma segment A3DControlRes
  3776.  
  3777. void T3DIconButton::Dim ()        // Override
  3778. {
  3779.     Inherited::Dim ();
  3780.  
  3781. } // T3DIconButton::Dim
  3782.  
  3783. //----------------------------------------------------------------------------------------
  3784. // T3DIconButton::SetIconSuite
  3785. //----------------------------------------------------------------------------------------
  3786. #pragma segment A3DControlNonRes
  3787.  
  3788. void T3DIconButton::SetIconSuite ( Handle theSuite, Boolean redraw )
  3789. {
  3790.  
  3791.     Inherited::SetIconSuite ( theSuite, redraw );
  3792.  
  3793.     this->SetAlignment ( atAbsoluteCenter, redraw );
  3794.  
  3795. } // T3DIconButton::SetIconSuite
  3796.  
  3797. //----------------------------------------------------------------------------------------
  3798. // T3DIconButton::SetIconSuiteRsrcID
  3799. //----------------------------------------------------------------------------------------
  3800. #pragma segment A3DControlNonRes
  3801.  
  3802. void T3DIconButton::SetIconSuiteRsrcID ( short itsRsrcID,
  3803.                                         IconSelectorValue selectorValue,
  3804.                                         Boolean redraw )
  3805. {
  3806.     Inherited::SetIconSuiteRsrcID ( itsRsrcID, selectorValue, redraw );
  3807.     this->SetAlignment ( atAbsoluteCenter,redraw );
  3808.  
  3809. } // T3DIconButton::SetIconSuiteRsrcID
  3810.  
  3811. //----------------------------------------------------------------------------------------
  3812. // T3DIconButton::SetIconRsrcID
  3813. //----------------------------------------------------------------------------------------
  3814. #pragma segment A3DControlNonRes
  3815.  
  3816. void T3DIconButton::SetIconRsrcID ( short itsRsrcID, Boolean redraw )
  3817. {
  3818.     VRect theRect;
  3819.     IconSelectorValue selectorValue;
  3820.  
  3821.     this->ControlArea ( theRect );
  3822.     switch ( this->GetIconSize ( theRect.GetSize () ) )
  3823.     {
  3824.     case 12:
  3825.         selectorValue = svAllMiniData;
  3826.         break;
  3827.     case 16:
  3828.         selectorValue = svAllSmallData;
  3829.         break;
  3830.     case 32:
  3831.         selectorValue = svAllLargeData;
  3832.         break;
  3833.     }
  3834.  
  3835.     this->SetIconSuiteRsrcID ( itsRsrcID, selectorValue, redraw );
  3836.  
  3837. } // T3DIconButton::SetIconRsrcID
  3838.  
  3839. //----------------------------------------------------------------------------------------
  3840. // T3DIconButton::SetMode
  3841. //----------------------------------------------------------------------------------------
  3842. #pragma    segment    A3DControlOpen
  3843.  
  3844. void T3DIconButton::SetMode ( ButtonMode newMode )
  3845. {
  3846.     fMode = newMode;
  3847.  
  3848. }    // T3DIconButton::SetMode
  3849.  
  3850. //----------------------------------------------------------------------------------------
  3851. // T3DIconButton::GetMode
  3852. //----------------------------------------------------------------------------------------
  3853. #pragma    segment    A3DControlOpen
  3854.  
  3855. ButtonMode T3DIconButton::GetMode ()
  3856. {
  3857.     return fMode;
  3858.  
  3859. }    // T3DIconButton::GetMode
  3860.  
  3861. //----------------------------------------------------------------------------------------
  3862. // T3DIconButton::IsSelected
  3863. //----------------------------------------------------------------------------------------
  3864. #pragma    segment    A3DControlNonRes
  3865.  
  3866. Boolean T3DIconButton::IsSelected ( void )
  3867. {
  3868.     return fHilite;
  3869.  
  3870. }    // T3DIconButton::IsSelected
  3871.  
  3872. //----------------------------------------------------------------------------------------
  3873. // T3DIconButton::TrackMouse
  3874. //----------------------------------------------------------------------------------------
  3875. #pragma segment A3DControlSelCommand
  3876.  
  3877. void T3DIconButton::TrackMouse (    TrackPhase aTrackPhase,
  3878.                                      VPoint& ,
  3879.                                      // anchorPoint
  3880.                                      VPoint& ,
  3881.                                      // previousPoint
  3882.                                      VPoint& nextPoint,
  3883.                                      Boolean )                            // OVERRIDE
  3884. {
  3885.     if (!this->IsDimmed())
  3886.         switch (aTrackPhase)
  3887.         {
  3888.         case trackBegin:
  3889.             fState = fHilite;
  3890.             this->HiliteState ( true, kRedraw );
  3891.             break;
  3892.         case trackContinue:
  3893.             if (this->ContainsMouse ( nextPoint ))
  3894.                 this->HiliteState ( true, kRedraw );
  3895.             else
  3896.                 this->HiliteState ( fState, kRedraw);
  3897.             break;
  3898.         case trackEnd:
  3899.             if (this->ContainsMouse ( nextPoint ))
  3900.             {
  3901.                 switch ( fMode )
  3902.                 {
  3903.                 case kButtonMode:
  3904.                     if ( fHilite )
  3905.                         this->HiliteState ( false, kRedraw);
  3906.                     break;
  3907.                 case kSwitchMode:
  3908.                     this->HiliteState ( !fHilite, kRedraw);
  3909.                     break;
  3910.                 case kRadioMode:
  3911.                     if ( !fHilite )
  3912.                         this->HiliteState ( true, kRedraw );
  3913.                     break;
  3914.                 }
  3915.  
  3916.                 this->HandleEvent ( fEventNumber, this, NULL );
  3917.             }
  3918.             break;
  3919.         }
  3920. }    // T3DIconButton::TrackMouse
  3921.